framework

Mybatis

MyBatis的$和#的区别

1
select * from user where name = #{name};

解析为:

1
select * from user where name = ?;

而${ } 仅仅为一个纯碎的 string 替换,在动态 SQL 解析阶段将会进行变量替换

sql注入user; delete user; ,那么就会删除整张表

Mybatis流程

  1. 读取配置文件
  2. 加载Mybatis映射
  3. 加载sqlSessionFactory
  4. 创建sqlSession
  5. Executor执行器
  6. 设置MapStatement
  7. 输入映射
  8. 输出映射

Spring

@Bean 和 @Component的区别是什么?

  • @Component 注解作用于类,而@Bean注解作用于方法。
  • @Bean 注解比 @Component 注解的自定义性更强

@Autowired 和 @Resource 的区别是什么?

@Autowired 是 Spring 提供的注解,@Resource 是 JDK 提供的注解。

@autowired byType,@Qualifier(指定名称)

@Resource byName(默认)

Bean的作用域

单例,prototype(每次一个),request(每个请求一个),每个session一个,global(一个web应用一个),一个websocket一个

单例bean的线程安全问题

多个线程操作的是一个bean,避免可变的成员变量,需要的时候使用threadlocal

Bean的生命周期

  1. 创建一个实例,调用构造方法
  2. 填充属性
  3. 设置beanName、beanFactory、ApplicationContext
  4. 前置处理
  5. 检查是否需要是初始化bean来决定调用afterPropertiesSet()
  6. init方法
  7. 后置处理
  8. 使用bean
  9. 执行disposableBean方法
  10. destroy()

IOC容器初始化过程

  1. 定位资源路径
  2. 构建ioc容器
  3. 解析xml文件
  4. 这一步是将document对象解析成spring内部的bean结构,实际上是AbstractBeanDefinition对象。
  5. 注册BeanDefition里

循环依赖

一级缓存是得concurrentHashMap

二级缓存和三级缓存是HashMap

bean创建基本过程

  1. 实例化 createInstance,完成之后会加入三级缓存
  2. 属性注入 populateBean 如果依赖了其他的bean会从各级缓存中查找,如果在三级缓存中找到了,会将其放入二级缓存
  3. 初始化 initializeBean 会将bean加入到一级缓存,清除各级缓存

一级缓存中存储的是已经完全创建好了的单例Bean

image-20200706133018669

AOP

AOP(Aspect-Oriented Programming:面向切面编程)能够将那些与业务无关,却为业务模块所共同调用的逻辑或责任(例如事务处理、日志管理、权限控制等)封装起来,便于减少系统的重复代码,降低模块间的耦合度,并有利于未来的可拓展性和可维护性。

如果实现了某个接口就会使用jdk代理,如果没有就会使用cglib生成子类代理。

Spring AOP 属于运行时增强(proxy),而 AspectJ 是编译时增强。(字节码)

before

after

afterReturning

afterThrowing

动态代理

Jdk动态代理

必须是实现接口的类,创建实现该接口的代理,通过反射完成

Cglib动态代理

创建该类的子类,进行代理,使用ASM框架修改字节码

SpringMvc

处理流程

  1. http请求到DispatchServlet
  2. 查看配置的handlerMapping,查找对应处理器
  3. 调用适配处理器Adapter,适配处理器调用真正的handler
  4. handler返回modelAndView
  5. 调用视图处理器viewResolver
  6. 根据model渲染视图
  7. 返回结果

Spring事务

编程式事务管理

显示提交到TransactionManager

声明式事务管理

@Transactional 注解只能在public方法能用

隔离级别

同数据库

读未提交

可重复读

读已提交

串行

传播行为

required:父子方法使用同一个事务,子方法抛出异常整个事务都会回滚,无论是否捕捉异常。

required_new:父子方法使用不同的事务,子方法抛出异常父方法的事务不会回滚。

nested:父子方法使用同一个事务,事务是否回滚取决于父方法是否对子方法的异常做处理,处理了就不会回滚。

如果抛出非 RuntimeException 和非 Error 错误的其他异常,就不会回滚

使用原理

动态代理

作者

leon Yan

发布于

2023-06-15

更新于

2023-09-18

许可协议


评论