0、参考文章
- (35条消息) 阿里面试真题:Spring容器启动流程_敖丙-CSDN博客_spring容器启动流程
- spring容器的refresh方法分析 - xuanm - 博客园 (cnblogs.com)
- 请别再问Spring Bean的生命周期了! - 简书 (jianshu.com)
- Spring Bean的生命周期(非常详细) - Chandler Qian - 博客园 (cnblogs.com)
- https://www.zhihu.com/question/438247718/answer/1730527725
- https://www.jianshu.com/p/b2349564a915
1、spring容器初始化过程
-
使用BeanDefinitionReader 加载配置文件(xml、propertity、配置类),将其读取并解析到容器内
-
实例化BeanDefinition接口实现类(是否懒加载、是否单例、是否是原型、是否是抽象类、类信息、别名信息)
-
获得BeanFactory, 默认是DefaultListableBeanFactory
-
设置BeanFactory的一些属性值,类加载器、添加部分beanPostProcessor、设置忽略自动装配接口、系统属性、环境变量
-
注册和执行 invokBeanFactoryPostProcessor,可以自己实现BeanFactoryPostProcessor接口实现控制,例如修改BD的是否懒加载、单例修改为原型等, spring留的扩展,spring自带的有PropertyPlaceHolderConfigure
-
注册 BeanPostProcessor,可以扩展
-
初始化国际化相关
-
创建事件传播器对象
-
注册监听器–实现ApplicationListener接口并放到容器中
-
预实例化Bean,核心流程:
-
总的分为:获得mdb、实例化依赖、实例化本对象、填充属性、初始化、销毁, 重要接口:BeanPostProcessor、InstantiationAwareBeanPostProcessor
-
获取MergedBeanDefinition ----- 合并父类beanDefinition
-
有没有配置depends-on依赖,如果有依赖,先实例化depends-on的类
-
实例化对象 createBeanInstance, 实例化阶段前后会调用 InstantiationAwareBeanPostProcessor
-
填充属性 populateBean
-
调用aware接口相关的方法:invokeAwareMethod(完成BeanName,BeanFactory,BeanClassLoader对象的属性设置)
-
调用BeanPostProcessor中的前置处理方法:使用比较多的有(ApplicationContextPostProcessor,设置ApplicationContext,Environment,ResourceLoader,EmbeddValueResolver等对象)
-
调用initmethod方法:invokeInitmethod(),判断是否实现了initializingBean接口,如果有,调用afterPropertiesSet方法,没有就不调用
-
调用BeanPostProcessor的后置处理方法:spring的aop就是在此处实现的,
-
注册Destuction相关的回调接口:钩子函数
-
使用中
-
是否实现了DisPosableBean接口
-
-
生成完整对象,通过getBean获取
-
销毁
2、谈谈你对IOC的理解
总:IOC:inverse of control,控制反转,将对对象的控制放到spring容器中, 包括创建、使用、销毁
DI: 依赖注入, 容器自动将对象的依赖注入到属性中
容器:存放具体对象,使用map结构存储,一般存在三级缓存中
3、spring 三级缓存
- singletonObjects: 保存实例化、注入、初始化完成的bean
- earlySingletonObjects: 保存实例化完成的bean
- singletonFactories: 保存 bean创建工厂,以便于后面扩展有机会创建代理对象
4、循环依赖问题
定义: A依赖B,B依赖A; A依赖B,B依赖C,C依赖A
三种循环依赖类型:
- 构造方法循环依赖 不能解决
- 单例setter注入 能解决
- 多例setter注入 不能解决
5、AOP的底层实现
总: AOP, 面向切面编程, 是IOC的容器初始化过程中的一个扩展点, 主要体现在 beanPostProcessor中
整个过程:
- 代理对象的创建过程:找到合适的通知器 、切面、切点
- 通过JDK或者CGLIB的方式生成代理对象
- 在执行方法调用的时候,会调用到生成的字节码文件中,直接转到DynamicAdvisoredInterceptor类中的intercept方法,从此方法开始执行
- 根据之前定义好的通知来生成拦截器链
- 从拦截器链中获取每一个通知进行执行
6、Spring的事务是如何回滚的
- 事务分为声明式事务和编程式事务,我们一般用的比较多的是声明式事务
- spring的事务管理是如何实现的?
总:spring的事务是由aop来实现的,首先要生成具体的代理对象,然后按照aop的整套流程来执行具体的操作逻辑,正常情况下要通过通知来完成核心功能,但是事务不是通过通知来实现的,而是通过一个TransactionInterceptor来实现的,然后调用invoke来实现具体的逻辑
分:1、先做准备工作,解析各个方法上事务相关的属性,根据具体的属性来判断是否开始新事务
2、当需要开启的时候,获取数据库连接,关闭自动提交功能,开起事务
3、执行具体的sql逻辑操作
4、在操作过程中,如果执行失败了,那么会通过completeTransactionAfterThrowing看来完成事务的回滚操作,回滚的具体逻辑是通过doRollBack方法来实现的,实现的时候也是要先获取连接对象,通过连接对象来回滚
5、如果执行过程中,没有任何意外情况的发生,那么通过commitTransactionAfterReturning来完成事务的提交操作,提交的具体逻辑是通过doCommit方法来实现的,实现的时候也是要获取连接,通过连接对象来提交
6、当事务执行完毕之后需要清除相关的事务信息cleanupTransactionInfo
7、spring的事务传播
传播特性有几种?7种
Required,Requires_new,nested,Support,Not_Support,Never,Mandatory
某一个事务嵌套另一个事务的时候怎么办?
A方法调用B方法,AB方法都有事务,并且传播特性不同,那么A如果有异常,B怎么办,B如果有异常,A怎么办?
总:事务的传播特性指的是不同方法的嵌套调用过程中,事务应该如何进行处理,是用同一个事务还是不同的事务,当出现异常的时候会回滚还是提交,两个方法之间的相关影响,在日常工作中,使用比较多的是required,Requires_new,nested
分:1、先说事务的不同分类,可以分为三类:支持当前事务,不支持当前事务,嵌套事务
2、如果外层方法是required,内层方法是,required,requires_new,nested
3、如果外层方法是requires_new,内层方法是,required,requires_new,nested
4、如果外层方法是nested,内层方法是,required,requires_new,nested