Springbean的生命周期
虽然大概知道springbean
的生命周期的过程,但怕这老年人记忆,过段时间就忘了,故本篇将记录一下常用生命周期节点,以及事件的一些节点。
BeanPostProcessor
下图为BeanPostProcessor
的接口方法以及它的扩展接口的方法,这些接口就是贯穿spring
一个bean
创建完成的全过程。
简单看一下这些接口的方法。
BeanPostProcessor
1 | public interface BeanPostProcessor { |
MergedBeanDefinitionPostProcessor
1 | public interface MergedBeanDefinitionPostProcessor extends BeanPostProcessor { |
InstantiationAwareBeanPostProcessor
1 | public interface InstantiationAwareBeanPostProcessor extends BeanPostProcessor { |
SmartInstantiationAwareBeanPostProcessor
1 | public interface SmartInstantiationAwareBeanPostProcessor extends InstantiationAwareBeanPostProcessor { |
具体在bean
创建过程中的哪一个环节中使用到。
- 这里判断正要实例化的
bean
是否需要被代理,也就是这个扩展点允许开发者干预springbean
的创建流程,若开发者实现这个方法并返回代理对象,这是仅是调用BeanPostProcessor#postProcessAfterInitialization
后就将对象打入容器中,不会走springbean
的创建流程。 - 这个扩展点就是为了第1点中的情况结合使用。
- 推断构造函数,在没有指定构造函数时,可以通过这个扩展点,进行推断构造函数,
@PostConstruct
注解就是通过实现这个扩展点实现。 - 这个扩展点用于动态修改
BeanDefinition
后进行合并父子BeanDefinition
。 - 这个扩展点在
populateBean()
方法的较前位置,主要判断这个bean
是否允许进行属性的依赖注入,若这个扩展方法返回false
,则表示不允许进行依赖注入,所以就不注入属性依赖,直接返回原对象。 - 这里先执行
InstantiationAwareBeanPostProcessor
的postProcessProperties
方法,若这个接口返回值为空时,则执行postProcessPropertyValues
方法。@Autowired
和@Resource
注解就是通过实现这个扩展点进行属性注入。 - 这个扩展点是在处理循环依赖时,当正在创建的
beanA
需要注入还未创建的beanB
时,通过这个扩展点来获取beanB
,这时可以通过这个扩展点对beanB
对象进行一些处理,比如SpringAOP
就是在这个扩展点上对beanB
实现了代理对象,将代理对象注入到正在创建的beanA
中。 - 这个扩展点就是顶层接口
BeanPostProcessor
后置处理器的postProcessorBeforeInitialization
。比如CommonAnnotationBeanPostProcessor
的父类InitDestroyAnnotationBeanPostProcessor
实现了这个方法,在这个方法中处理@PostConstruct
注解标记方法的反射调用。 - 这个扩展点就是顶层接口
BeanPostProcessor
后置处理器的postProcessorAfterInitialization
。比如AbstractAutoProxyCreator
使用这个方法对创建完成的bean
进行AOP
代理。
事件机制的生命周期
spring
的事件机制实际上就是发布订阅模式的实现,且spring
内置就有好几个伴随着spring
容器生命周期的事件,但好像使用比较多的是被springboot
扩展的事件,springboot
通过实现ApplicationEvent
抽象类,又扩展了一些事件。
springboot
中的事件:SpringApplicationEvent
是springboot
的所有事件接口的抽象父接口
ApplicationStartingEvent
:框架启动发送事件,在springboot
的启动方法中,当调用run
方法后,随之就发送该事件。ApplicationEnvironmentPreparedEvent
:环境准备完成发送事件,在步骤1事件发送之后,springboot
就进行读取启动命令行参数以及environment
的处理,完成该处理后发生时间。ApplicationContextInitializedEvent
:Spring上下文初始化完成且在加载bean之前发送,在SpringApplication#prepareContext
方法中触发该事件。ApplicationPreparedEvent
:Spring上下文准备完成且Bean尚未加载完成,在SpringApplication#prepareContext
的最后触发该事件,这个事件发送之后就进入spring
的核心方法refresh
。ApplicationStartedEvent
:在spring
的refresh
方法执行完毕之后发送该事件,表示容器启动完成。ApplicationReadyEvent
:在SpringApplication#run
方法的最后,发送该事件。
以上6个事件是依次执行,根据上述信息可得,spring
内置的事件的执行时期,应该是在第四步骤中。