Bean生命周期
过程概述
创建对象
实例化(构造方法)
依赖注入
初始化
执行Aware接口回调
执行BeanPostProcessor.psotProcessBeforeInitialization
执行InitializingBean回调(先执行@PostConstruct)
执行BeanPsotProcessor.postProcessAfterInitialization
使用对象
销毁对象
执行DisposableBean回调(先执行@PreDestory)
源码解析
创建对象
实例化(构造方法)
依赖注入
初始化
执行Aware接口回调
执行BeanPostProcessor.psotProcessBeforeInitialization
执行InitializingBean回调(先执行@PostConstruct)
执行BeanPsotProcessor.postProcessAfterInitialization
使用对象
销毁对象
执行DisposableBean回调(先执行@PreDestory)
答案提取
总:Bean的生命周期总的来说有四个阶段,分别由创建对象、初始化对象、使用对象和销毁对象,而且这些工作大部分是交给Bean工厂的doCreateBean方法完成的
分: 首先,在创建对象阶段,先调用构造方法实例化对象,对象有了后回填充该对象的内容,其实就是处理依赖注入
其次,对象创建完毕后,需要做一些初始化的操作,涉及到如下几点:
1.执行Aware感知接口的回调方法
2.执行Bean后置处理器的postProcessBeforeInitialization方法
3.执行InitializingBean接口的回调,在这一步如果Bean中有标注了@PostConstruct注解的方法,会先执行它
4.执行Bean后置处理器的postProcessAfterInitialization
在这些操作都执行完了以后,Bean的初始化也就算完成了
接下来,在试用阶段就是程序员从容器中获取Bean使用
最后,在容器销毁之前,会先销毁对象,此时会执行DisposableBean接口的回调,这一步如果Bean中标注了@PreDestory接口的函数,会先执行它
总:简单总结,Bean的生命周期共包含四个阶段,其中初始化对象和销毁对象是可以有程序员自身的扩展发挥的空间
Bean循环依赖
循环依赖是指依赖闭环的问题
SPring默认是不允许循环依赖的存在的
可以通过配置文件让Spring解决循环依赖问题
过程概述
源码解析
答案获取
总:Bean的循环依赖是指A依赖B,B又依赖A这样的依赖闭环问题,在Spring中,通过三个对象缓存区来解决循环依赖问题,这三个缓存区被定义到了DefaultSingletonBeanRegistry中,分别是singletonObjects用来存储创建完毕的Bean、earlySingletonObjects用来存储未完成依赖注入的Bean,还有SingletonFactories用来存储创建Bean的ObjectFactory。假如说现在A依赖B,B依赖A,整个Bean的创建过程就下面这样的:
分:首先,调用A的构造方法实例化A,当前的A还有没处理依赖注入,此事暂且将它称为半成品,这个半成品A会封装到一个ObjectFactory中,存储到SpringFactories缓存区里
接下来会处理A的依赖注入,由于此时B实例还不存在,所以会先实例化一个B,当然,这个B的实例也会被封装到ObjectFactory中,存储到springFactories缓存区中
紧接着要处理的就是B的依赖注入,此时会先从SpringFactories中找到A对应的ObjectFactory,调用它的getObject方法得到刚刚的半成品实例化A(如果休要代理对象,则会自动创建代理对象,将来得到的就是代理对象,这里引申出第三层存在的意义,为了处理动态代理问题,如果不考虑动态代理问题,仅用前两层就可以解决循环依赖问题),把得到的半成品A注入给B,并同时会把半成品A存入到earlySingletonObjects中,将来如果还有其他类的循环依赖了A,就可以直接从earlySingletonObjects中找到它,那么此时springFactories中创建的存储A的ObjectFactory也就可以删除了
至此,B中的依赖注入处理完毕,B也就创建完毕了,B对象就会被存入到singletonObjects中去,同时,springFactories中创建的存储有B对象的ObjectFactory也就被删除了
B创建完毕后就要继续处理A的依赖注入了,将完成品B注入给A以后,A也就创建完毕了,就可以把A对象有人存入到singletonObjects中,并且删除掉earlySingletonObjects中存储的半成品A
至此,A,B都实例化完成,完成品都呗存入到singletonObjects中,将来通过容器获取对象,都是从singletonObjects中获取
总:总结起来是一句话,借助于DefaultSingletonBeanRegistry的三个缓冲区来解决循环依赖问题