0%

Springbean的生命周期

Springbean的生命周期

​ 虽然大概知道springbean的生命周期的过程,但怕这老年人记忆,过段时间就忘了,故本篇将记录一下常用生命周期节点,以及事件的一些节点。

BeanPostProcessor

下图为BeanPostProcessor的接口方法以及它的扩展接口的方法,这些接口就是贯穿spring一个bean创建完成的全过程。

BeanPostProcessor扩展点.png

简单看一下这些接口的方法。

  1. BeanPostProcessor
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
public interface BeanPostProcessor {

/**
* 初始化之前调用方法
*/
@Nullable
default Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
return bean;
}

/**
* 初始化之后调用方法
*/
@Nullable
default Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
return bean;
}

}
  1. MergedBeanDefinitionPostProcessor
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
public interface MergedBeanDefinitionPostProcessor extends BeanPostProcessor {

/**
* 合并RootBeanDefinition
*/
void postProcessMergedBeanDefinition(RootBeanDefinition beanDefinition, Class<?> beanType, String beanName);

/**
* A notification that the bean definition for the specified name has been reset,
* and that this post-processor should clear any metadata for the affected bean.
* <p>The default implementation is empty.
* @param beanName the name of the bean
* @since 5.1
* @see DefaultListableBeanFactory#resetBeanDefinition
*/
default void resetBeanDefinition(String beanName) {
}

}
  1. InstantiationAwareBeanPostProcessor
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
public interface InstantiationAwareBeanPostProcessor extends BeanPostProcessor {

/**
* 实例化之前的操作, 用于创建一个bean对象可能是一个代理用于替代目标对象
*/
@Nullable
default Object postProcessBeforeInstantiation(Class<?> beanClass, String beanName) throws BeansException {
return null;
}

/**
* 是否允许注入校验
* 实例化之后的操作, 在populateBean方法中,如果返回false表示不允许进行注入,直接跳出方法
* 相当于populateBean的前置校验方法,若跳出则表示什么都没有注入。
*/
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;
}

}
  1. SmartInstantiationAwareBeanPostProcessor
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
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创建过程中的哪一个环节中使用到。

BeanPostProcessor具体调用点.png

  1. 这里判断正要实例化的bean是否需要被代理,也就是这个扩展点允许开发者干预springbean的创建流程,若开发者实现这个方法并返回代理对象,这是仅是调用BeanPostProcessor#postProcessAfterInitialization后就将对象打入容器中,不会走springbean的创建流程。
  2. 这个扩展点就是为了第1点中的情况结合使用。
  3. 推断构造函数,在没有指定构造函数时,可以通过这个扩展点,进行推断构造函数,@PostConstruct注解就是通过实现这个扩展点实现。
  4. 这个扩展点用于动态修改BeanDefinition后进行合并父子BeanDefinition
  5. 这个扩展点在populateBean()方法的较前位置,主要判断这个bean是否允许进行属性的依赖注入,若这个扩展方法返回false,则表示不允许进行依赖注入,所以就不注入属性依赖,直接返回原对象。
  6. 这里先执行InstantiationAwareBeanPostProcessorpostProcessProperties方法,若这个接口返回值为空时,则执行postProcessPropertyValues方法。@Autowired@Resource注解就是通过实现这个扩展点进行属性注入。
  7. 这个扩展点是在处理循环依赖时,当正在创建的beanA需要注入还未创建的beanB时,通过这个扩展点来获取beanB,这时可以通过这个扩展点对beanB对象进行一些处理,比如SpringAOP就是在这个扩展点上对beanB实现了代理对象,将代理对象注入到正在创建的beanA中。
  8. 这个扩展点就是顶层接口BeanPostProcessor后置处理器的postProcessorBeforeInitialization。比如CommonAnnotationBeanPostProcessor的父类InitDestroyAnnotationBeanPostProcessor实现了这个方法,在这个方法中处理@PostConstruct注解标记方法的反射调用。
  9. 这个扩展点就是顶层接口BeanPostProcessor后置处理器的postProcessorAfterInitialization。比如AbstractAutoProxyCreator使用这个方法对创建完成的bean进行AOP代理。

事件机制的生命周期

spring的事件机制实际上就是发布订阅模式的实现,且spring内置就有好几个伴随着spring容器生命周期的事件,但好像使用比较多的是被springboot扩展的事件,springboot通过实现ApplicationEvent抽象类,又扩展了一些事件。

springboot中的事件SpringApplicationEventspringboot的所有事件接口的抽象父接口

springboot事件监听类继承关系.png

  1. ApplicationStartingEvent:框架启动发送事件,在springboot的启动方法中,当调用run方法后,随之就发送该事件。
  2. ApplicationEnvironmentPreparedEvent:环境准备完成发送事件,在步骤1事件发送之后,springboot就进行读取启动命令行参数以及environment的处理,完成该处理后发生时间。
  3. ApplicationContextInitializedEvent:Spring上下文初始化完成且在加载bean之前发送,在SpringApplication#prepareContext方法中触发该事件。
  4. ApplicationPreparedEvent:Spring上下文准备完成且Bean尚未加载完成,在SpringApplication#prepareContext的最后触发该事件,这个事件发送之后就进入spring的核心方法refresh
  5. ApplicationStartedEvent:在springrefresh方法执行完毕之后发送该事件,表示容器启动完成。
  6. ApplicationReadyEvent:在SpringApplication#run方法的最后,发送该事件。

以上6个事件是依次执行,根据上述信息可得,spring内置的事件的执行时期,应该是在第四步骤中。

-------------本文结束感谢您的阅读-------------