Bean的生命周期与循环依赖

如有不对的地方,还请大佬指正

Bean生命周期

扫描类 得到 BeanDefinition(包含bean的class等属性值)  
后在BeanFactoryPostProcessor对bean实例化之前对Bean的元数据进行操作,修改Bean的属性值、添加自定义的BeanDefinition
实例化非懒加载单例bean
  1. 实例化
  2. 属性填充         (自定义属性赋值)  
  3. Aware回调     (Aware只作为标识,根据标识给对应属性赋值,容器对象属性赋值)
  4. 初始化
  5. 添加到单例池

image-20231209181253972

扫描,得到BeanDefiniction–>BeanFactoryProcessor修改Bean的属性值–>实例化Bean–>设置bean对象的自定义属性–>判断Aware接口对容器对象属性赋值–>BeanPostProcessor(Aop)前置处理–>初始化(判断是否实现了initialzingBean,初始化属性)–>BeanPostProcessor后置处理–bean初始化完成–>使用–>销毁

bean的生命周期

依赖循环

依赖循环

二级缓存主要作用是保持未经过完全生命周期的Bean的单例。

构造器注入是没法通过三级缓存解决的

三级缓存存放的是创建对象的工厂,ObjectFactory,相当于延迟初始化。在AOP或者解决循环依赖时,通过调用Object的getObject()方法获取到第三级缓存中的对象。并且可以在调用时候,来判断返回的到底需要返回的代理对象还是原始对象

为什么要引入三级缓存
第三级缓存并非缺它不可,因为可以提前创建代理对象
但是提前创建代理对象会破坏spring的设计原则(尽可能地保证普通对象创建完成之后,再生成aop代理,即尽可能延迟代理对象的生成)
所以spring用来三级缓存,既维持了设计原则,又处理了循环依赖;牺牲了一点内存空间是可以接受的

为什么Sping不选择二级缓存方式,而是要额外加一层缓存?
如果要使用二级缓存解决循环依赖,意味着Bean在构造完后就创建代理对象,这样违背了Spring设计原则。Spring结合AOP跟Bean的生命周期,是在Bean创建完全之后通过AnnotationAwareAspectJAutoProxyCreator这个后置处理器来完成的,在这个后置处理的postProcessAfterInitialization方法中对初始化后的Bean完成AOP代理。如果出现了循环依赖,那没有办法,只有给Bean先创建代理,但是没有出现循环依赖的情况下,设计之初就是让Bean在生命周期的最后一步完成代理而不是在实例化后就立马完成代理

自动装配原理

1、当启动springboot应用程序的时候,会先创建SpringApplication的对象,在对象的构造方法中会进行某
些参数的初始化工作,最主要的是判断当前应用程序的类型以及初始化器和监听器,在这个过程中会加载整个应用
程序中的spring.factories文件,将文件的内容放到缓存对象中,方便后续获取。

2、SpringApplication对象创建完成之后,开始执行run方法,来完成整个启动,启动过程中最主要的有两个
方法,第一个叫做prepareContext,第二个叫做refreshContext,在这两个关键步骤中完整了自动装配的核心功
能,前面的处理逻辑包含了上下文对象的创建,banner的打印,异常报告期的准备等各个准备工作,方便后续来
进行调用。

3、在prepareContext方法中主要完成的是对上下文对象的初始化操作,包括了属性值的设置,比如环境对
象,在整个过程中有一个非常重要的方法,叫做load,load主要完成一件事,将出並应就美<为个
beanDefinition注册到registry中,方便后续在进行BeanFactoryPostProcessor调用执行的时候,找到对应的主
类,来完成@SpringBootApplicaiton,@EnableAutoConfiguration等注解的解析工作

4、在refreshContext方法中会进行整个容器刷新过程,会调用中spring中的refresh方法,refresh中有13个
非常关键的方法,来完成整个spring应用程序的启动,在自动装配过程中,会调用
invokeBeanFactoryPostProcessor方法,在此方法中主要是对ConfigurationClassPostProcessor类的处理,这次
是BFPP的子类也是BDRPP的子类,在调用的时候会先调用BDRPP中的postProcessBeanDefinitionRegistry方
法,然后调用postProcessBeanFactory方法,在执行postProcessReanDefinitionRegistry的时候回解析处理各种
注解,包含@PropertySource,@ComponentScan,@ComponentScans,@Bean,@lmport等注解,最主要的是
@lmport注解的解析

5、在解析@lmport注解的时候,会有一个getlmports的方法,从主类开始递归解析注解,把所有包含
@lmport的注解都解析到,然后在processlmport方法中对lmport的类进行分类,此处主要识别的时候
AutoConfigurationlmportSelect归属于ImportSelect的子类,在后续过程中会调用
deferredlmportSelectorHandler中的process方法,来完整EnableAutoConfiguration的加载。

  • 16
    点赞
  • 28
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值