Spring bean到底是如何创建的?(下)
本文是接着上篇文章 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:如果觉得这篇文章对你有帮助,欢迎大家关注公众号、分享、点赞、在看。