[Spring]影响Spring Bean生命周期的BeanPo
前言
Spring中使用了许多BeanPostPorcessor
来处理回调,在了解Spring Bean的生命周期时,会发现充斥着许多BeanPostProcessor
的方法执行.了解这些Spring框架的BeanPostProcessor
,来试图找到一些AOP有关的线索.
从整体的视角来看,Spring IoC
支持以注解驱动的方式来创建与管理对象,那么Spring AOP
是用来代理对象的,没有了对象,空谈Spring AOP是无意义的。在前面分析getBean
的流程中,我们也找到了一些AOP的蛛丝马迹,下面我们从BeanPostcessor的角度来看看在Bean的生命周期中一些关键的后置处理器.
UML
UML-
InstantiationAwareBeanPostProcessor:
InstantiationAwareBeanPostProcessor
是BeanPostProcessor
的子接口,主要是用于Spring框架内部使用 -
SmartInstantiationAwareBeanPostProcessor: 扩展InstantiationAwareBeanPostProcessor接口,添加了用于预测已处理bean的最终类型的回调、声明构造函数等.
-
AbstractAutoProxyCreator: 使用AOP代理包装每个合格的bean,并在调用bean本身之前委派给指定的拦截器
-
MergedBeanDefinitionPostProcessor: 主要处理合并BeanDefinition的回调,其中一个经典的接口为
postProcessMergedBeanDefinition
,用来找到被Spring支持的注解所标记的元数据。 -
AutowiredAnnotationBeanPostProcessor: 提供对Spring内部定义的注解支持:
@Autowired
、@Value
、@Lookup
,同时也支持@Inject
注解来声明注入 -
CommonAnnotationBeanPostProcessor: 提供对JSR注解的支持,常见的注解有
@PostConstruct
、@PreDestroy
、@Resource
. -
ApplicationContextAwareProcessor: 将
ApplicationContext
传递给实现EnvironmentAware
,EmbeddedValueResolverAware
,ResourceLoaderAware
,ApplicationEventPublisherAware
,MessageSourceAware
或ApplicationContextAware
接口的bean。 -
DestructionAwareBeanPostProcessor: 用于添加破坏前的回调。
典型的用法是在特定的bean类型上调用自定义销毁回调,并与相应的初始化回调匹配。
InstantiationAwareBeanPostProcessor
InstantiationAwareBeanPostProcessor是BeanPostProcessor
的子接口,主要是用于Spring框架内部使用,它有3个回调方法,通常用于抑制特定目标Bean的默认实例化,例如,创建具有特殊TargetSource的代理(池目标,延迟初始化目标等),或实施其他注入策略,例如字段注入:
- postProcessBeforeInstantiation
在实例化目标bean(doCreateBean)之前应用此BeanPostProcessor。返回的Bean对象可以是代替目标Bean使用的代理,从而有效地抑制了目标Bean的默认实例化。
如果此方法返回一个非null对象,则bean创建过程将被短路。可以应用自已配置BeanPostProcessors的postProcessAfterInitialization回调来进一步处理。
- postProcessAfterInstantiation
通过构造函数或工厂方法在实例化bean之后但在发生Spring属性填充(通过显式属性或自动装配)之前执行操作。
这是在Spring的自动装配开始之前对给定的bean实例执行自定义字段注入的理想回调。
默认实现返回true。
- postProcessProperties
在beanFactory将其作为getBean的返回值前,对给定的属性值(比如被Spring框架的注解标注的成员)进行后处理,无需使用属性描述符(property descriptors)。
这个关键的方法便是populateBean中的@Autowired
注解解析入口.
SmartInstantiationAwareBeanPostProcessor
Spring框架内部使用的专用接口,扩展了
InstantiationAwareBeanPostProcessor
接口,在整个Spring Bean的生命周期中,会经常与该接口打交道。
-
predictBeanType:
预测从此处理器的postProcessBeforeInstantiation
回调最终返回的bean的类型。
默认实现返回null。
Bean在经过postProcessBeforeInstantiation
处理后也许返回了代理类,那么此处即提前声明好代理后的对象类型. -
determineCandidateConstructors
声明给定bean所要应用的候选构造函数。
org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#determineConstructorsFromBeanPostProcessors
中使用了该方法用于Bean的实例化过程中推断构造函数,如果能从SmartInstantiationAwareBeanPostProcessor
中获取到构造函数数组,那么直接使用该构造函数数组进行对象实例化. -
getEarlyBeanReference
提前暴露引用,用于解决循环依赖问题.
MergedBeanDefinitionPostProcessor
AutowiredAnnotationBeanPostProcessor
和CommonAnnotationBeanPostProcessor
都实现了此接口,用于查找被Spring所支持的注解所标记的元数据. 在doCreateBean
中,会调用applyMergedBeanDefinitionPostProcessors
对此后置处理器进行统一激活.
下面贴一下经典的案例:
- AutowiredAnnotationBeanPostProcessor#postProcessMergedBeanDefinition
@Override
/**
* InjectionMetadata-内部类,用于管理注入元数据。不适用于直接在应用程序中使用。
*/
public void postProcessMergedBeanDefinition(RootBeanDefinition beanDefinition, Class<?> beanType, String beanName) {
// 扫描当前Class是否有被@Autowired、@Value标记的成员变量,最终封装到InjectionMetadata中
InjectionMetadata metadata = findAutowiringMetadata(beanName, beanType, null);
// 将Spring容器需要用默认策略注入的 element 保存到 checkedElements 中
metadata.checkConfigMembers(beanDefinition);
}
ApplicationContextAwareProcessor
主要用于处理实现了Aware接口的回调.重写了BeanPostProcessor
的postProcessBeforeInitialization
方法.在AbstractAutowireCapableBeanFactory#initializeBean
中,工厂会先执行invokeAwareMethods
来激活BeanNameAware
、BeanClassLoaderAware
、BeanFactoryAware
,其他的Aware接口交由此后置处理器进行激活.
@Override
@Nullable
public Object postProcessBeforeInitialization(final Object bean, String beanName) throws BeansException {
AccessControlContext acc = null;
if (System.getSecurityManager() != null &&
(bean instanceof EnvironmentAware || bean instanceof EmbeddedValueResolverAware ||
bean instanceof ResourceLoaderAware || bean instanceof ApplicationEventPublisherAware ||
bean instanceof MessageSourceAware || bean instanceof ApplicationContextAware)) {
acc = this.applicationContext.getBeanFactory().getAccessControlContext();
}
if (acc != null) {
AccessController.doPrivileged((PrivilegedAction<Object>) () -> {
invokeAwareInterfaces(bean);
return null;
}, acc);
}
else {
invokeAwareInterfaces(bean);
}
return bean;
}
// 激活实现了Aware的接口: EnvironmentAware、EmbeddedValueResolverAware
// ResourceLoaderAware、ApplicationEventPublisherAware、MessageSourceAware
// ApplicationContextAware
private void invokeAwareInterfaces(Object bean) {
if (bean instanceof Aware) {
if (bean instanceof EnvironmentAware) {
((EnvironmentAware) bean).setEnvironment(this.applicationContext.getEnvironment());
}
if (bean instanceof EmbeddedValueResolverAware) {
((EmbeddedValueResolverAware) bean).setEmbeddedValueResolver(this.embeddedValueResolver);
}
if (bean instanceof ResourceLoaderAware) {
((ResourceLoaderAware) bean).setResourceLoader(this.applicationContext);
}
if (bean instanceof ApplicationEventPublisherAware) {
((ApplicationEventPublisherAware) bean).setApplicationEventPublisher(this.applicationContext);
}
if (bean instanceof MessageSourceAware) {
((MessageSourceAware) bean).setMessageSource(this.applicationContext);
}
if (bean instanceof ApplicationContextAware) {
((ApplicationContextAware) bean).setApplicationContext(this.applicationContext);
}
}
}
DestructionAwareBeanPostProcessor
在销毁Bean前执行Bean所声明的自定义销毁方法.
假设一个Bean实现了DisposableBean
,那么在Spring Bean初始化的时候就会注册销毁方法,在Spring对Bean进行销毁的时候,通过此后置处理器进行统一激活。
流程图
1 2以下是今天文章所讲的BeanPostProcessor对Spring Bean生命周期的管理.