Spring Bean 的生命周期,如何被管理的

对于普通的 Java对象,当 new的时候创建对象,当它没有任何引用的时候被垃圾回收机制回收。而由Spring IoC容器托管的对象,它们的生命周期完全由容器控制。Spring 中每个 Bean的生命周期如下:加了一些过滤条件(黑色框的平时基本上不会用到)。那分别介绍下面的流程。

【1】实例化 Bean:对于 BeanFactory 容器,当客户向容器请求一个尚未初始化的 bean时,或初始化 bean的时候需要注入另一个尚未初始化的依赖时,容器就会调用 createBean进行实例化。对于 ApplicationContext容器,当容器启动结束后,便实例化所有的单实例 bean。容器通过获取 BeanDefinition对象中的信息进行实例化。并且这一步仅仅是简单的实例化,并未进行依赖注入。实例化对象被包装在 BeanWrapper 对象中,BeanWrapper 提供了设置对象属性的接口,从而避免了使用反射机制设置属性。通过工厂方法或者执行构造器解析执行即可:创建的对象是个空对象。
【2】设置对象属性(依赖注入):实例化后的对象被封装在 BeanWrapper对象中,并且此时对象仍然是一个原生的状态,并没有进行依赖注入。紧接着获取所有的属性信息通过 populateBean(beanName,mbd,bw,pvs),Spring 根据 BeanDefinition 中的信息进行依赖注入。并且通过 BeanWrapper提供的设置属性的接口完成依赖注入。赋值之前获取所有的 InstantiationAwareBeanPostProcessor 后置处理器的 postProcessAfterInstantiation()  第二次获取InstantiationAwareBeanPostProcessor 后置处理器;执行 postProcessPropertyValues()最后为应用 Bean属性赋值:为属性利用 setter 方法进行赋值 applyPropertyValues(beanName,mbd,bw,pvs)。
【3】bean 初始化:initializeBean(beanName,bean,mbd)。
    1)执行xxxAware 接口的方法,调用实现了BeanNameAware、BeanClassLoaderAware、BeanFactoryAware接口的方法。
    2)执行后置处理器之前的方法:applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName)所有后置处理器的 BeanPostProcessor.postProcessBeforeInitialization()
    3)执行初始化方法: InitializingBean 与 init-methodinvoke 当 BeanPostProcessor的前置处理完成后就会进入本阶段。先判断是否实现了 InitializingBean接口的实现;执行接口规定的初始化。其次自定义初始化方法。
InitializingBean 接口只有一个函数:afterPropertiesSet()这一阶段也可以在 bean正式构造完成前增加我们自定义的逻辑,但它与前置处理不同,由于该函数并不会把当前 bean对象传进来,因此在这一步没办法处理对象本身,只能增加一些额外的逻辑。若要使用它,我们需要让 bean实现该接口,并把要增加的逻辑写在该函数中。然后 Spring会在前置处理完成后检测当前 bean是否实现了该接口,并执行 afterPropertiesSet函数。当然,Spring 为了降低对客户代码的侵入性,给 bean的配置提供了 init-method属性,该属性指定了在这一阶段需要执行的函数名。Spring 便会在初始化阶段执行我们设置的函数。init-method 本质上仍然使用了InitializingBean接口。
    4)applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);执行初始化之后的后置处理器的方法。BeanPostProcessor.postProcessAfterInitialization(result, beanName);
【4】Bean的销毁:DisposableBean 和 destroy-method:和 init-method 一样,通过给 destroy-method 指定函数,就可以在bean 销毁前执行指定的逻辑。

Bean 的管理就是通过 IOC 容器中的 BeanDefinition 信息进行管理的。
 

发布了95 篇原创文章 · 获赞 2 · 访问量 3546

猜你喜欢

转载自blog.csdn.net/m0_37235955/article/details/105400982