这是我参与2022首次更文挑战的第3天,活动详情查看:2022首次更文挑战
虽然大概知道springbean的生命周期的过程,但怕这老年人记忆,过段时间就忘了,故本篇将记录一下常用生命周期节点,以及事件的一些节点。
BeanPostProcessor
下图为BeanPostProcessor的接口方法以及它的扩展接口的方法,这些接口就是贯穿spring一个bean创建完成的全过程。
简单看一下这些接口的方法。
BeanPostProcessor主要包含两个接口,一个是初始化之前调用的方法,一个是初始化之后调用的方法。
public interface BeanPostProcessor {
default Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
return bean;
}
default Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
return bean;
}
}
MergedBeanDefinitionPostProcessor:主要是用来合并RootBeanDefinition
public interface MergedBeanDefinitionPostProcessor extends BeanPostProcessor {
void postProcessMergedBeanDefinition(RootBeanDefinition beanDefinition, Class<?> beanType, String beanName);
default void resetBeanDefinition(String beanName) {
}
}
InstantiationAwareBeanPostProcessor①实例化之前的操作, 用于创建一个bean对象可能是一个代理用于替代目标对象
②是否允许注入校验实例化之后的操作, 在populateBean方法中,如果返回false表示不允许进行注入,直接跳出方法相当于populateBean的前置校验方法,若跳出则表示什么都没有注入。
③主要就是处理 通过注解注入属性的一系列操作
public interface InstantiationAwareBeanPostProcessor extends BeanPostProcessor {
/**
* ①
*/
@Nullable
default Object postProcessBeforeInstantiation(Class<?> beanClass, String beanName) throws BeansException {
return null;
}
/**
* ②
*
*/
default boolean postProcessAfterInstantiation(Object bean, String beanName) throws BeansException {
return true;
}
/**
* ③
*/
@Nullable
default PropertyValues postProcessProperties(PropertyValues pvs, Object bean, String beanName) throws BeansException {
return null;
}
/**
* 弃用
*/
@Deprecated
@Nullable
default PropertyValues postProcessPropertyValues(PropertyValues pvs, PropertyDescriptor[] pds, Object bean, String beanName) throws BeansException {
return pvs;
}
}
SmartInstantiationAwareBeanPostProcessor
public interface SmartInstantiationAwareBeanPostProcessor extends InstantiationAwareBeanPostProcessor {
/**
* 推断构造函数
*/
@Nullable
default Constructor<?>[] determineCandidateConstructors(Class<?> beanClass, String beanName)throws BeansException {
return null;
}
/**
* 处理循环依赖时使用,获取提前暴露对象
*/
default Object getEarlyBeanReference(Object bean, String beanName) throws BeansException {
return bean;
}
}
具体在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内置的事件的执行时期,应该是在第四步骤中。