查看原文
其他

Spring bean到底是如何创建的?(下)

三友 三友的java日记 2022-06-22

本文是接着上篇文章   Spring bean到底是如何创建的?(上) 来继续讲述spring bean的其它的生命周期。


前文回顾:


上篇文章最开始我简单介绍了spring ioc和aop的概念,随后讲述了spring bean创建源码分析的一部分,包括bean元信息、不同作用域bean的创建方式、bean的后置处理器BeanPostProcessor组件体系、三级缓存解决循环依赖的问题、bean 的实例化阶段的源码。接下来这篇会继续从源码的角度来分析bean生命周期的其它阶段,包括 bean属性赋值阶段、Aware接口回调阶段、bean初始化阶段、bean的销毁阶段的内容。


五、 Spring Bean属性赋值阶段

        1)赋值前阶段

        2)赋值阶段

六、 Aware接口回调阶段

七、 Spring Bean初始化阶段

        1)初始化之前阶段

        2)初始化阶段

        3)初始化之后阶段

八、Spring Bean销毁阶段

         1)DisposableBean的注册

         2)销毁前阶段

         3)销毁阶段

九、全文总结

十、思考题


五、 Spring Bean属性赋值阶段


1)属性赋值前阶段


这个阶段需要对bean的一些属性进行赋值。比如说@Autowired 、@Resource等注解都是在这个阶段生效的。



PropertyValues:这个api是封装属性的。不知道大家记不记得,当用xml配置bean的时候是可以通过标签给属性赋值的,其实当spring对配置信息解析之后会封装在PropertyValues中。



看看,这里其实有又是对BeanPostProcessor组件接口的回调。@Autowired 、@Resource 注解就是在这时生效的。


我给大家列举一下在这个阶段一些重要的实现类,大家有时间可以翻一下源码,自己阅读一下这些实现类的 postProcessProperties 方法,看看注解是怎么生效的。


AutowiredAnnotationBeanPostProcessor:处理@Autowired、@Value注解

CommonAnnotationBeanPostProcessor:这个类的功能比较多,主要是实现了 @PostConstruct 、@PreDestory 、 @Resource 注解的功能,当然是在不同的阶段生效的,只不过spring 都给他写在同一个类中了


除了spring的实现,你还可以自己实现postProcessProperties ,因为你看这个方法的返回值是 PropertyValues ,属性的封装,所以可以在方法实现的时候往 PropertyValues 添加一些数据,这样就给属性赋值的时候就按照你设置的属性来赋值了。


2)属性赋值阶段


继续往下走



这里会给属性赋值,所谓的赋值其实很简单,就是从 PropertyValues  拿出配置的属性以及对应的属性的值,然后设置到属性中其实就行了。只不过这里可能涉及到一些类型的转换和占位符的解析,还有一些其它的特性,这里就不详细展开讲了。


六、 Aware接口回调阶段


这个阶段主要是会判断你有没有实现某些Aware接口,如果你实现了的话,spring会调用这些接口。


populateBean方法结束了,接下来进入initializeBean方法



进入 invokeAwareMethods方法




当你的bean实现了这些接口,spring会回调你的bean这些接口的实现


七、 Spring Bean初始化阶段


属性赋值完和Aware接口回调完之后,会进入对象的初始化阶段


1)初始化之前阶段




其实也还是BeanPostProcessor方法的回调


这里有一个实现类,叫 ApplicationContextAwareProcessor,这个类跟上面Aware回调阶段干的事差不多,其实就是判断你有没有实现哪些接口,如果实现了,就会回调你实现接口的方法。


2)初始化阶段


 接下来进入invokeInitMethods方法




这里进行了bean的初始化,就是如果你的bean实现了InitializingBean接口或者你配置了自定义的initMethod(xml中有属性可以配置,@Bean注解的initMethod属性配置),这里就会回调你的方法


3)初始化之后阶段




这些阶段继续回调BeanPostProcessor方法,其实在这个阶段,就完成了对于对象的动态代理的生成,具体是由 AspectJAwareAdvisorAutoProxyCreator 这个实现完成的,大家可以自己翻一下这个实现类的postProcessAfterInitialization方法,是在这个类的父类中实现的。


到这里为止,一个单例的bean就被完完整整的给创建出来了,你平时使用的对象也就是这个对象。


接下来就是将对象放在 singletonObjects 缓存中,如果下次有查询的话,就直接从这个缓存中查找出来返回(上一篇文章说过,先查询,如果查不到再创建)


八、Spring Bean销毁阶段


这个阶段不属于bean的创建阶段,你平时使用的bean在上一个阶段就完完全全创建好了,这个阶段是在spring容器关闭的时候才会执行。


 1)DisposableBean的注册


接下来继续往下走





这个阶段就是将bean给包裹成一个DisposableBean,也就是DisposableBeanAdapter对象,给放到disposableBeans中,但是要想放到disposableBeans中是要有条件的比如你实现了DisposableBean接口,或者在xml中配置销毁的方法名或通过@Bean的属性的destoryMethod方法中指定了方法名等,具体的条件可以进入hasDestroyMethod方法中查看


2)bean 销毁前阶段


spring bean 什么时候会销毁?


当项目停止的时候,会回调ApplicationContext的close()方法(是由AbstractApplicationContext实现的),这个回去调用doClose()方法,doClose()方法会去回调BeanFactory(由DefaultListableBeanFactory实现)的destroySingleton方法,然后回调用父类DefaultSingletonBeanRegistry方法,从这开始就开始就进行单例bean的销毁。


我们直接定位到DefaultSingletonBeanRegistry的destroySingleton方法



根据bean名称从disposableBeans中取出上面注册的DisposableBean,然后调用destroyBean方法



这里我们可以看出,是直接调用我们注册的DisposableBean,也就是DisposableBeanAdapter事件的destroy方法,接下来我们进入destroy方法



这里就是又是BeanPostProcessor组件方法的回调


3)bean的销毁阶段



如果我们自己的bean是实现了DisposableBean接口,那么spring会回调这个方法的实现


接下来就是回调我们配置的销毁的回调方法



至此,bean就被销毁了。


九、全文总结


到这里整个spring bean生命周期源码分析就完全讲完了,包括了bean创建和销毁,其实bean的生命周期说白了就是在bean创建和销毁的不同阶段进行BeanPostProcessor组件方法的回调来达到对于bean的创建或销毁过程扩展的目的。其实我们自己也可以在项目中实现BeanPostProcessor接口来达到自己的目的。在讲述spring bean的生命周期的时候,我也提到了bean的作用域、spring是如何使用三级缓存解决循环依赖等问题。相信这两篇文章看完之后大家对spring bean创建和销毁的过程都有一个全面的了解。



十、思考题


你知道spring还有哪些功能是通过扩展BeanPostProcessor来实现的么?除了spring之外有哪些框架是通过扩展BeanPostProcessor实现跟spring整合的?


PS:如果觉得这篇文章对你有帮助,欢迎大家关注公众号、分享、点赞、在看。

您可能也对以下帖子感兴趣

文章有问题?点此查看未经处理的缓存