【Spring】典型 BeanPostProcessor 的调用时机及代表实现类总结
- 前言
- 1)SmartInstantiationAwareBeanPostProcessor#predictBeanType
- 2)InstantiationAwareBeanPostProcessor#postProcessBeforeInstantiation
- 3)SmartInstantiationAwareBeanPostProcessor#determineCandidateConstructors
- 4)MergedBeanDefinitionPostProcessor#postProcessMergedBeanDefinition
- 5)SmartInstantiationAwareBeanPostProcessor#getEarlyBeanReference
- 6)InstantiationAwareBeanPostProcessor#postProcessAfterInstantiation
- 7)InstantiationAwareBeanPostProcessor#postProcessProperties
- 8)BeanPostProcessor#postProcessBeforeInitialization
- 9)BeanPostProcessor#postProcessAfterInitialization
- 总结
前言
BeanPostProcessor
是 Spring
留给我们让我们自定义拓展 bean实例
生命周期的 钩子
接口
本文总结几类核心 BeanPostProcessor
的调用时机、顺序,以及几个代表实现类的业务逻辑
该文可以看作是下文的一个延伸与补充
Spring —— BeanPostProcessor 后处理器梳理
行文顺序以创建 bean实例
时调用后处理器的时机为准
1)SmartInstantiationAwareBeanPostProcessor#predictBeanType
- 该方法调用处较多,入口为
AbstractApplicationContext#getBeanNamesForType
,主要用于推断InstantiationAwareBeanPostProcessor#postProcessBeforeInstantiation
方法返回的bean
类型 - 默认情况下遵从默认实现返回
null
,但因为AbstractAutoProxyCreator
在postProcessBeforeInstantiation
方法中是可能提前返回代理实例
的,因此AbstractAutoProxyCreator
也给出了对应的predictBeanType
方法实现
2)InstantiationAwareBeanPostProcessor#postProcessBeforeInstantiation
此方法调用处在 AbstractAutowireCapableBeanFactory#createBean
方法中,创建 bean实例对象
之前,主要是进行实例化前的处理
根据它的方法名也不难猜测:
postProcessBeforeInstantiation:实例化之前处理
@Override
protected Object createBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args)
throws BeanCreationException {
RootBeanDefinition mbdToUse = mbd;
/**
* 此处是确保 beanClass 已解析完成
*/
Class<?> resolvedClass = resolveBeanClass(mbd, beanName);
if (resolvedClass != null && !mbd.hasBeanClass() && mbd.getBeanClassName() != null) {
mbdToUse = new RootBeanDefinition(mbd);
mbdToUse.setBeanClass(resolvedClass);
}
try {
mbdToUse.prepareMethodOverrides();
}
catch (BeanDefinitionValidationException ex) {
}
try {
/**
* 这里会先调用一次 InstantiationAwareBeanPostProcessor#postProcessBeforeInstantiation 方法
* 如果返回一个 null 则会短路其生命周期,执行 postProcessAfterInitialization 后返回
*
* 在 AOP 代理阶段,此处是有可能提前短路的
*/
Object bean = resolveBeforeInstantiation(beanName, mbdToUse);
if (bean != null) {
return bean;
}
}
catch (Throwable ex) {
}
try {
// 创建 bean实例 并返回
Object beanInstance = doCreateBean(beanName, mbdToUse, args);
return beanInstance;
}
catch (Throwable ex) {
}
}
- 在
bean实例对象
实例化之前,调用resolveBeforeInstantiation
方法,如果返回非null
实例,则直接作为createBean
的结果返回 -
resolveBeforeInstantiation
的逻辑为:执行所有InstantiationAwareBeanPostProcessor#postProcessBeforeInstantiation
方法,如果有返回非null
对象,则短路其生命周期,直接执行postProcessAfterInitialization
方法后返回 - 通常情况下,此处都是返回
null
,但在AOP
的实现中,InstantiationAwareBeanPostProcessor
的实现类AbstractAutoProxyCreator
:如果指定了TargetSource
,则此处会提前返回对应的代理对象
,即:短路剩余生命周期后直接返回
3)SmartInstantiationAwareBeanPostProcessor#determineCandidateConstructors
该方法的调用时机在创建实例的 AbstractAutowireCapableBeanFactory#createBeanInstance
方法中,一般情况下,初次获取的 bean
在没有 factoryMethod
(@Bean
注解方法)时,便需要推断其构造方法
protected BeanWrapper createBeanInstance(String beanName, RootBeanDefinition mbd, @Nullable Object[] args) {
// ...
// 如果指定 InstanceSupplier,则直接通过它获取实例
Supplier<?> instanceSupplier = mbd.getInstanceSupplier();
if (instanceSupplier != null) {
return obtainFromSupplier(instanceSupplier, beanName);
}
// 如果存在 FactoryMethod,比如 @Bean 注解的对应方法,则依此获取实例
if (mbd.getFactoryMethodName() != null) {
return instantiateUsingFactoryMethod(beanName, mbd, args);
}
/**
* 如果已经解析过,便直接创建即可
*/
boolean resolved = false;
boolean autowireNecessary = false;
if (args == null) {
synchronized (mbd.constructorArgumentLock) {
if (mbd.resolvedConstructorOrFactoryMethod != null) {
resolved = true;
autowireNecessary = mbd.constructorArgumentsResolved;
}
}
}
if (resolved) {
if (autowireNecessary) {
return autowireConstructor(beanName, mbd, null, null);
}
else {
return instantiateBean(beanName, mbd);
}
}
/**
* 交给所有 SmartInstantiationAwareBeanPostProcessor#determineCandidateConstructors 来推断,
* 返回第一个不为空的构造器数组
*/
Constructor<?>[] ctors = determineConstructorsFromBeanPostProcessors(beanClass, beanName);
if (ctors != null || mbd.getResolvedAutowireMode() == AUTOWIRE_CONSTRUCTOR ||
mbd.hasConstructorArgumentValues() || !ObjectUtils.isEmpty(args)) {
return autowireConstructor(beanName, mbd, ctors, args);
}
// 默认构造
ctors = mbd.getPreferredConstructors();
if (ctors != null) {
return autowireConstructor(beanName, mbd, ctors, null);
}
return instantiateBean(beanName, mbd);
}
- 如果没有指定
InstanceSupplier
或者没有对应的factoryMethod
,便会执行所有SmartInstantiationAwareBeanPostProcessor#determineCandidateConstructors
,返回第一个不为空的构造器数组
-
factoryMethod
主要是在配置类
解析时,@Bean
方法会被解析成对应实例的factoryMethod
- 一般地,该逻辑默认由
AutowiredAnnotationBeanPostProcessor
实现:在解析到对应的构造方法后,则会基于此构造方法来构造实例,实现对于构造方法中诸如@Autowired
参数的赋值
4)MergedBeanDefinitionPostProcessor#postProcessMergedBeanDefinition
该方法的调用在 AbstractAutowireCapableBeanFactory#doCreateBean
方法中,当创建完目标 bean
对应的实例对象后,此处对对应的 BeanDefinition
进行后处理
protected Object doCreateBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args)
throws BeanCreationException {
/**
* 构造(或从缓存获取)对应 bean实例 的 BeanWrapper
*/
BeanWrapper instanceWrapper = null;
if (mbd.isSingleton()) {
instanceWrapper = this.factoryBeanInstanceCache.remove(beanName);
}
if (instanceWrapper == null) {
instanceWrapper = createBeanInstance(beanName, mbd, args);
}
Object bean = instanceWrapper.getWrappedInstance();
Class<?> beanType = instanceWrapper.getWrappedClass();
if (beanType != NullBean.class) {
mbd.resolvedTargetType = beanType;
}
/**
* 实例创建完成后,调用所有
* MergedBeanDefinitionPostProcessor#postProcessMergedBeanDefinition
* 对目标 bean实例 的 BeanDefinition 进行后处理
*/
synchronized (mbd.postProcessingLock) {
if (!mbd.postProcessed) {
try {
applyMergedBeanDefinitionPostProcessors(mbd, beanType, beanName);
}
catch (Throwable ex) {
}
mbd.postProcessed = true;
}
}
// ...
}
-
BeanWrapper
是一个基于内省
给实例属性赋值的PropertyAccessor
,唯一实现类BeanWrapperImpl
- 在实例对应的
BeanWrapper
创建完成后,回调用所有MergedBeanDefinitionPostProcessor#postProcessMergedBeanDefinition
对目标bean
的BeanDefinition
进行后处理 - 此处的实现类较多,也是
Spring
的一个核心拓展点,列举一二: - 1)
ApplicationListenerDetector
,在此阶段会把所有自定义的ApplicationListener
先收录到singletonNames
中,后续注册进容器 - 2)
AutowiredAnnotationBeanPostProcessor
,基于@Autowired
@Value
@Inject
注解将对应需要注入的元素(包括Field
Method
)封装成对应的InjectedElement
,最后构造成对应的InjectionMetadata
,后续会试图对上述元素构造对应的PropertyValues
用于属性填充 - 3)
CommonAnnotationBeanPostProcessor
,与AutowiredAnnotationBeanPostProcessor
类似,处理的是@Resource
的注解
5)SmartInstantiationAwareBeanPostProcessor#getEarlyBeanReference
该方法的调用在 bean
实例化完成后、属性填充前,对于需要 循环依赖
的 bean实例
(是单例 & BeanFactory
本身支持循环依赖 & 当前正在被循环依赖),此处会提前返回一个实例暴露给对应的 单例工厂(二级缓存)
protected Object doCreateBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args)
throws BeanCreationException {
// ...
// 对于 循环依赖 的单例此处现提前暴露实例给单例工厂(二级缓存)
boolean earlySingletonExposure = (mbd.isSingleton() && this.allowCircularReferences &&
isSingletonCurrentlyInCreation(beanName));
if (earlySingletonExposure) {
addSingletonFactory(beanName, () -> getEarlyBeanReference(beanName, mbd, bean));
}
// ...
}
- 此处主要是为了解决
循环依赖
,提前将实例暴露到单例工厂 - 默认实现即返回实例本身,但在
AOP
的实现中,AbstractAutoProxyCreator
在此处返回对应的代理对象
6)InstantiationAwareBeanPostProcessor#postProcessAfterInstantiation
该方法的调用在属性填充方法 AbstractAutowireCapableBeanFactory#populateBean
中,在确定要进行属性填充之前,此处会执行这组后处理器,判断是否跳过
protected void populateBean(String beanName, RootBeanDefinition mbd, @Nullable BeanWrapper bw) {
// 空处理 ...
/**
* 此处是调用所有的 InstantiationAwareBeanPostProcessor#postProcessAfterInstantiation
* 但凡有返回 false,此处就 return 不继续注入了,目前的默认实现都是 true
*/
if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) {
for (InstantiationAwareBeanPostProcessor bp : getBeanPostProcessorCache().instantiationAware) {
if (!bp.postProcessAfterInstantiation(bw.getWrappedInstance(), beanName)) {
return;
}
}
}
// ...
}
- 但凡有一个
InstantiationAwareBeanPostProcessor#postProcessAfterInstantiation
返回false
,此处会放弃填充之前return
- 默认实现返回
true
,目前未看到用途,猜测是可以注册在自定义的容器上下文中,进行自定义的属性注入
7)InstantiationAwareBeanPostProcessor#postProcessProperties
该方法的调用在属性填充方法 AbstractAutowireCapableBeanFactory#populateBean
中,在确定要进行属性填充后,便会执行所有 InstantiationAwareBeanPostProcessor#postProcessProperties
,此处允许对属性填充所需的 PropertyValues
进行处理
protected void populateBean(String beanName, RootBeanDefinition mbd, @Nullable BeanWrapper bw) {
// ...
boolean hasInstAwareBpps = hasInstantiationAwareBeanPostProcessors();
boolean needsDepCheck = (mbd.getDependencyCheck() != AbstractBeanDefinition.DEPENDENCY_CHECK_NONE);
PropertyDescriptor[] filteredPds = null;
/**
* 如果存在 InstantiationAwareBeanPostProcessor
* 则基于 InstantiationAwareBeanPostProcessor#postProcessProperties
* 构造最终的 PropertyValues
*/
if (hasInstAwareBpps) {
if (pvs == null) {
pvs = mbd.getPropertyValues();
}
for (InstantiationAwareBeanPostProcessor bp : getBeanPostProcessorCache().instantiationAware) {
PropertyValues pvsToUse = bp.postProcessProperties(pvs, bw.getWrappedInstance(), beanName);
if (pvsToUse == null) {
if (filteredPds == null) {
filteredPds = filterPropertyDescriptorsForDependencyCheck(bw, mbd.allowCaching);
}
// 有 postProcessPropertyValues 来兜底
pvsToUse = bp.postProcessPropertyValues(pvs, filteredPds, bw.getWrappedInstance(), beanName);
if (pvsToUse == null) {
return;
}
}
pvs = pvsToUse;
}
}
// 依赖校验...
// PropertyValues 的属性绑定...
}
-
PropertyValues
中对应属性的赋值最终委托是BeanWrapper
实现的 - 此处的实现类也不少,最最核心的就是
AutowiredAnnotationBeanPostProcessor
:基于之前解析的InjectedElement
,进行属性赋值 - 此处如果解析为
null
,则继续交给InstantiationAwareBeanPostProcessor#postProcessPropertyValues
方法,它的本质其实与前者一样,只是后者已被标注@Deprecated
,用来兜底,之后应该会被移除
8)BeanPostProcessor#postProcessBeforeInitialization
该方法的调用是在实例初始化 AbstractAutowireCapableBeanFactory#initializeBean
方法中,此处的 bean
已经完成实例化并且填充完属性,进入初始化阶段,在这之前,进行初始化前处理
protected Object initializeBean(String beanName, Object bean, @Nullable RootBeanDefinition mbd) {
/**
* invokeAwareMethods:
* 执行 BeanNameAware BeanClassLoaderAware BeanFactoryAware 回调
*/
if (System.getSecurityManager() != null) {
AccessController.doPrivileged((PrivilegedAction<Object>) () -> {
invokeAwareMethods(beanName, bean);
return null;
}, getAccessControlContext());
}
else {
invokeAwareMethods(beanName, bean);
}
/**
* 执行所有 BeanPostProcessor#postProcessBeforeInitialization:初始化前处理
*/
Object wrappedBean = bean;
if (mbd == null || !mbd.isSynthetic()) {
wrappedBean = applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName);
}
try {
/**
* 初始化:
* 1)InitializingBean#afterPropertiesSet
* 2)init-method 回调
*/
invokeInitMethods(beanName, wrappedBean, mbd);
}
catch (Throwable ex) {
}
// ...
}
- 执行初始化操作之前调用,根据方法名也能看出来
- 初始化操作主要有:1)
InitializingBean#afterPropertiesSet
方法的执行 2)init-method
调用,比如@Bean
注解指定、@PostConstruct
注解标注的方法 - 列举几个代表实现:
- 1)
ApplicationContextAwareProcessor
:执行各种Aware
回调诸如EnvironmentAware
ApplicationContextAware
等 - 2)
BeanValidationPostProcessor
:对当前bean
的属性进行validate
验证
9)BeanPostProcessor#postProcessAfterInitialization
该方法的调用在初始化相关操作之后,此时 bean实例
的初始化已完成,进行初始化后处理
protected Object initializeBean(String beanName, Object bean, @Nullable RootBeanDefinition mbd) {
// ...
try {
/**
* 初始化:
* 1)InitializingBean#afterPropertiesSet
* 2)init-method 回调
*/
invokeInitMethods(beanName, wrappedBean, mbd);
}
catch (Throwable ex) {
}
/**
* 执行所有 BeanPostProcessor#postProcessAfterInitialization:初始化后处理
*/
if (mbd == null || !mbd.isSynthetic()) {
wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);
}
return wrappedBean;
}
-
bean实例
初始化操作完成后调用 - 列举几个代表实现:
- 1)
AbstractAutoProxyCreator
:大名鼎鼎的AOP代理
一般就是在这个阶段实现,创建对应的代理对象后返回 - 2)
ApplicationListenerDetector
:会把之前收录的自定义监听器beanName
,注册到容器中 - 3)
BeanValidationPostProcessor
:再次对bean实例
属性进行validate
验证
总结
BeanPostProcessor
是 Spring
暴露出来的核心拓展点,基于这些处理器,我们可以干涉到 bean实例
的个阶段生命周期,以实现各种定制化的需求
因此,明确清晰的了解各类处理器的执行时机是十分有必要的,本文的目的也是为了全面的梳理上述 BeanPostProcessor
的执行时机即功能,才能更加灵活的运用与拓展