spring 和 springboot的区别
自动配置原理
beanFactory接口和ApplicationContext接口
两个都是 IOC 容器
ApplicationContext接口是BeanFactory接口实现类的子类
功能:
ApplicationContext扩展BeanFactory
BeanFactory | ApplicationContext |
---|---|
控制反转 | 国际化支持 (MessageSource) |
依赖注入 | 资源访问 (ResourcePatternResolver根据通配符匹配文件) |
读取环境信息(EnvironmentCapable ) | |
bean生命周期的全部功能: 读取bean配置文档,管理bean的定义,加载,实例化,维护bean之间的依赖关系,负责bean的声明周期 | 发布事件(ApplicationEventPublisher),事件传递 :通过实现ApplicationContextAware接口。 |
区别:
BeanFactory | ApplicationContext |
---|---|
功能需要以编程的方式实现 | 通过配置的方式实现 |
Spring里面最底层的接口,是IoC的核心 | 一般直接使用ApplicationContext |
手动注册BeanPostProcessor | 自动注册BeanPostProcessor |
延迟加载:在使用某个Bean时(调用getBean()),才对该Bean进行加载实例化,注入Bean。不能提前发现Spring的配置问题。调用getBean方法时会抛出异常。 | 在容器启动时,一次性创建了所有的Bean,预先载入。可以发现Spring中的配置错误,利于检查所依赖属性是否注入。运行时速度比较快,但占用内存空间,当应用程序配置Bean较多时,程序启动较慢。 |
实现
-
BeanFactory :先解析bean,将描述信息存入map,getBean时调用构造方法,实例化bean
对BeanFactory 添加BeanFactoryPostProcessor,补充bean的定义
对bean添加BeanPostProcessor,针对bean生命周期的各个阶段进行扩展BeanFactoryPostProcessor 是在 Spring 容器加载了定义 bean 的 XML 文件之后,在 bean 实例化之前执行的。读取配置元数据,并且可以修改
BeanPostProcessor 可以在 spring 容器加载了 bean 的定义文件并实例化 bean 之后,在执行 bean 的初始化方法前后,添加一些自己的处理逻辑。 有排序逻辑
初始化方法:
bean 实现 了 InitializingBean 接口,对应的方法为 afterPropertiesSet 。
在 XML 文件中定义 bean 的时候,标签有个属性叫做 init-method,来指定初始化方法。
BeanPostProcessor 的执行顺序是在 BeanFactoryPostProcessor 之后。 -
BeanFactory
- 不会主动调用BeanFactoryPostProcessor
- 不会主动添加BeanPostProcessor
- 不会主动初始化单例
- 不会解析BeanFactory
- 不会解析${} #{}
事务
事务隔离
Isolation.DEFAULT:默认的事务隔离级别,以连接的数据库的事务隔离级别为准。
Isolation.READ_UNCOMMITTED:读未提交,可以读取到未提交的事务,存在脏读。
Isolation.READ_COMMITTED:读已提交,只能读取到已经提交的事务,解决了脏读,存在不可重复读。
Isolation.REPEATABLE_READ:可重复读,解决了不可重复读,但存在幻读(MySQL 数据库默认的事务隔离级别)。
Isolation.SERIALIZABLE
传播行为
@transactional原理
通过aop的方式进行管理。动态代理
以 @Transactional 注解为植入点的切点,@Transactional注解标注的方法需要被代理。
在spring的bean的初始化过程中,就需要对实例化的bean进行代理,并且生成代理对象。
@Transactional注解的切面逻辑类似于@Around,
失效:
- @Transactional修饰的方法为非public方法, static final 也不行
失败的原理是:@Transactional是基于动态代理来实现的,非public的方法,他@Transactional的动态代理对象信息为空,所以不能回滚。 - 在类内部没有添加@Transactional的方法,调用了@Transactional方法时。
@Transactional是基于动态代理对象来实现的,而在类内部的方法的调用是通过this关键字来实现的,没有经过动态代理对象,所以事务回滚失效。 - @Transactional方法内部捕获了异常,没有在catch代码块里面重新抛出异常,事务也不会回滚。