一、前言
文章目录:Spring源码深度解析:文章目录
二、BeanPostProcessor
所谓的BeanPostProcessor
翻译过来就是Bean后处理器。
1. 什么是 BeanPostProcessor
BeanPostProcessor
是 Spring提供给我们的一个非常重要的扩展接口,并且Spring内部的很多功能也是通过 BeanPostProcessor
来完成的(目前看到最典型的就是AnnotationAwareAspectJAutoProxyCreator
的 注入)。
2. BeanPostProcessor 的种类
BeanPostProcessor
在Spring 中的子类非常多(idea 显是有46个),比如
InstantiationAwareBeanPostProcessorAdapter
: 在Spring 的bean
加载过程中起了非常重要的作用AnnotationAwareAspectJAutoProxyCreator
:bean
创建过程中的 属性注入时起作用AspectJAwareAdvisorAutoProxyCreator
: Aspect 的 AOP 功能实现也全仰仗BeanPostProcessor
的特性。
3. BeanPostProcessor 的创建
个人认为Bean
的创建时可以认为分为两个过程: 一是Bean
对应的BeanDefinition
的创建。二是Bean
实例的创建。
因为在 Spring容器中,Bean
的创建并非仅仅通过反射创建就结束了,在创建过程中,需要考虑到Bean
针对Spring容器中的一些属性,所以BeanDefinition
中不仅仅包含了Bean Class
文件信息,还包含了 当前Bean
在Spring容器中的一些属性,比如在容器中的作用域、是否懒加载、别名等信息。当Bean
进行实例化创建时需要依赖于对应的BeanDefinition
提供对应的信息。
BeanDefinition
的创建在 Spring 启动时对BeanFactoryPostProcessor
的处理。
详参:
Spring源码深度解析:五、BeanFactoryPostProcessor的处理
Spring源码深度解析:六、ConfigurationClassPostProcessor
Bean 实例的创建在Spring 启动时的收尾工作
详参:
Spring源码深度解析:三、容器的刷新 - refresh()
而由于BeanPostProcessor
是参与了Bean
创建过程。所以其创建一定在普通Bean
之前。实际上BeanPostProcessor
的创建时在Spring
启动时容器刷新的时候。
BeanPostProcessor
的BeanDefinition
创建时机和普通Bean
没有区别,都是在Spring 启动时的BeanFactoryPostProcessor
中完成(确切的说是ConfigurationClassPostProcessor
中完成)。
而BeanPostProcessor
的实例创建要优先于普通bean
创建,Spring启动过程中会调用AbstractApplicationContext#registerBeanPostProcessors
方法。 在这个方法中,Spring 会从容器中获取到所有BeanPostProcessor
类型的beanName
, 通过beanFactory.getBean
方法获取到对应实例,进行排序后注册到BeanFactory.beanPostProcessors
属性中,其中BeanFactory.beanPostProcessors
的定义如下
private final List<BeanPostProcessor> beanPostProcessors = new BeanPostProcessorCacheAwareList();
当容器需要执行 BeanPostProcessor
方法时可以直接从beanPostProcessors
中获取即可。
三、基本介绍
日常使用中,我们一般编写一个类来实现BeanPostProcessor
或者 InstantiationAwareBeanPostProcessor
接口,根据每个方法的调用时机,来完成响应的工作。
下面介绍一下接口方法,这里通过InstantiationAwareBeanPostProcessor
接口来介绍 。InstantiationAwareBeanPostProcessor
是BeanPostProcessor
的子接口,在 BeanPostProcessor
基础上又扩展了三个方法。
@Component
public class DemoPostProcessor implements InstantiationAwareBeanPostProcessor {
//InstantiationAwareBeanPostProcessor 提供的方法, 在 Class<T> -> T 的转换过程中
// 此时bean还没创建,可以通过这方法代替 Spring 容器创建的方法
@Override
public Object postProcessBeforeInstantiation(Class<?> beanClass, String beanName) throws BeansException {
System.out.println("DemoPostProcesser.postProcessBeforeInstantiation ### 1");
return null;
}
//InstantiationAwareBeanPostProcessor 提供的方法, 返回的值代表是否需要继续注入属性,
// 如果返回true,则会调用postProcessProperties和postProcessPropertyValues 来注入属性
// 此时bean已经创建,属性尚未注入
@Override
public boolean postProcessAfterInstantiation(Object bean, String beanName) throws BeansException {
System.out.println("DemoPostProcesser.postProcessAfterInstantiation ### 2");
return true;
}
//InstantiationAwareBeanPostProcessor 提供的方法,可以在这个方法中进行bean属性的注入, 这个方法已经过时,使用postProcessProperties 代理
// 只有postProcessAfterInstantiation 返回true 时 且 postProcessProperties 返回 null 时调用
@Override
public PropertyValues postProcessPropertyValues(PropertyValues pvs, PropertyDescriptor[] pds, Object bean, String beanName) throws BeansException {
System.out.println("DemoPostProcesser.postProcessPropertyValues ### 3");
return pvs;
}
// BeanPostProcessor 提供的方法,在bean初始化前调用,这时候的bean大体已经创建完成了,在完成一些其他属性的注入
@Override
public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
System.out.println("DemoPostProcesser.postProcessBeforeInitialization ### 4");
return bean;
}
// BeanPostProcessor 提供的方法,在bean初始化后调用,这时候的bean 已经创建完成了
@Override
public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
System.out.println("DemoPostProcesser.postProcessAfterInitialization ### 5");
return bean;
}
}
@Configuration
@ComponentScan("com.wts.BeanPostProcessorTest")
public class SpringConfigPostProcessor {
}
public class Test {
public static void main(String[] args) {
AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext(SpringConfigPostProcessor.class);
Object demoPostProcessor = applicationContext.getBean("demoPostProcessor");
System.out.println(demoPostProcessor);
}
}
四、源码中的调用场景
下面为了方便描述,进行一些简化写法,为了后面描述方便
BP : BeanPostProcessor
IBP : InstantiationAwareBeanPostProcessor
SBP : SmartInstantiationAwareBeanPostProcessor
其结构如下图:
这里就不具体贴出多少代码。简单解释一下调用场景
Spring 在启动过程中,会将所有实现了BeanPostProcessor
接口的子类保存到 AbstractBeanFactory
中的beanPostProcessors
集合中,如下:
private final List<BeanPostProcessor> beanPostProcessors = new CopyOnWriteArrayList<>();
在适当的时候(这个适当的时候就根据 每个接口方法定义的意义来判断), Spring会获取所有的BeanPostProcessor
子类集合,即beanPostProcessors
,经过类型过滤后,调用对应的方法。比如,就是对InstantiationAwareBeanPostProcessor.postProcessBeforeInstantiation
方法的调用流程(其余方法的调用也类似):
AbstractAutowireCapableBeanFactory#applyBeanPostProcessorsBeforeInstantiation()
@Nullable
protected Object applyBeanPostProcessorsBeforeInstantiation(Class<?> beanClass, String beanName) {
// 获取所有BeanPostProcessor进行遍历
for (BeanPostProcessor bp : getBeanPostProcessors()) {
// 因为只有 InstantiationAwareBeanPostProcessor 类型才有postProcessBeforeInstantiation 方法,所以这里要判断一下是不是 InstantiationAwareBeanPostProcessor 类型
if (bp instanceof InstantiationAwareBeanPostProcessor) {
InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp;
// 调用postProcessBeforeInstantiation方法
Object result = ibp.postProcessBeforeInstantiation(beanClass, beanName);
if (result != null) {
return result;
}
}
}
return null;
}
1. InstantiationAwareBeanPostProcessor
下面来介绍在 Spring 创建流程中 每个方法的实际调用位置:
1.1. postProcessBeforeInstantiation
InstantiationAwareBeanPostProcessor.postProcessBeforeInstantiation
方法在Bean
创建之前调用,我所理解的目的是替换Spring 容器创建bean
, 当InstantiationAwareBeanPostProcessor.postProcessBeforeInstantiation
返回不为null时,则不会再通过Spring 创建bean
,而是使用 InstantiationAwareBeanPostProcessor.postProcessBeforeInstantiation
返回的bean
。
AbstractAutowireCapableBeanFactory#createBean()
resolveBeforeInstantiation
方法内容如下,可以看到 当 applyBeanPostProcessorsBeforeInstantiation
方法(applyBeanPostProcessorsBeforeInstantiation
调用了postProcessBeforeInstantiation
方法) 返回值不为 null,则会调用 applyBeanPostProcessorsAfterInitialization
方法,从而调用postProcessAfterInitialization
方法。因为这里bean返回不为null,则代表bean创建成功了,就会调用创建成功后的方法,即postProcessAfterInitialization
。
AbstractAutowireCapableBeanFactory#resolveBeforeInstantiation()
@Nullable
protected Object resolveBeforeInstantiation(String beanName, RootBeanDefinition mbd) {
Object bean = null;
// 如果尚未被解析
if (!Boolean.FALSE.equals(mbd.beforeInstantiationResolved)) {
// Make sure bean class is actually resolved at this point.
// 当前类并非合成类 && 存在 BeanPostProcessor (后处理器)
if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) {
// 1. 获取目标类
Class<?> targetType = determineTargetType(beanName, mbd);
// 2. 实例前的后处理器应用
if (targetType != null) {
bean = applyBeanPostProcessorsBeforeInstantiation(targetType, beanName);
if (bean != null) {
// 3. 实例后的后处理器应用
bean = applyBeanPostProcessorsAfterInitialization(bean, beanName);
}
}
}
mbd.beforeInstantiationResolved = (bean != null);
}
return bean;
}
这里需要注意,在resolveBeforeInstantiation
方法中,当bean != null
时 调用了applyBeanPostProcessorsAfterInitialization
方法,即 BeanPostProcessor.postProcessAfterInitialization
方法。这是因为如果bean != null
, 则说明 bean 的创建已经完成,那么这里则是最后调用bean 的后置处理的机会,即调用BeanPostProcessor.postProcessAfterInitialization
方法的最后机会。
1.2. postProcessAfterInstantiation & postProcessPropertyValues
InstantiationAwareBeanPostProcessor.postProcessAfterInstantiation
、InstantiationAwareBeanPostProcessor.postProcessPropertyValues
的调用场景只有一处,在AbstractAutowireCapableBeanFactory#populateBean()
方法中,此时bean已经创建完成,正在进行属性注入。而InstantiationAwareBeanPostProcessor.postProcessAfterInstantiation
的返回值决定是否继续注入
protected void populateBean(String beanName, RootBeanDefinition mbd, @Nullable BeanWrapper bw) {
...
// 调用 postProcessAfterInstantiation 方法吗,如果返回false,直接return;
if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) {
for (BeanPostProcessor bp : getBeanPostProcessors()) {
if (bp instanceof InstantiationAwareBeanPostProcessor) {
InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp;
if (!ibp.postProcessAfterInstantiation(bw.getWrappedInstance(), beanName)) {
return;
}
}
}
}
...
if (hasInstAwareBpps || needsDepCheck) {
if (pvs == null) {
pvs = mbd.getPropertyValues();
}
PropertyDescriptor[] filteredPds = filterPropertyDescriptorsForDependencyCheck(bw, mbd.allowCaching);
if (hasInstAwareBpps) {
// 3. 成员变量的注入
// 调用了InstantiationAwareBeanPostProcessor.postProcessPropertyValues()方法,来进行设值后处理
for (BeanPostProcessor bp : getBeanPostProcessors()) {
if (bp instanceof InstantiationAwareBeanPostProcessor) {
InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp;
// 调用设值
pvs = ibp.postProcessPropertyValues(pvs, filteredPds, bw.getWrappedInstance(), beanName);
if (pvs == null) {
return;
}
}
}
}
// 如果需要检查
if (needsDepCheck) {
// 依赖检查,对应 depends-on属性,3.0 已弃用
checkDependencies(beanName, mbd, filteredPds, pvs);
}
}
...
}
通过代码我们可以比较清楚的看到整体逻辑:
- 若
InstantiationAwareBeanPostProcessor.postProcessAfterInstantiation
返回true,才会执行下面步骤 - 调用
InstantiationAwareBeanPostProcessor.postProcessPropertyValues
注入属性
2. BeanPostProcessor
2.1. postProcessBeforeInitialization
BeanPostProcessor.postProcessBeforeInitialization
调用时机是bean已经创建完成,但是尚未初始化,即一些属性配置尚未完成(我看到的就一个init-method
的配置)。使用场景也只有一处,即
AbstractAutowireCapableBeanFactory#initializeBean(String, Object, RootBeanDefinition)。
程序走到这里,代表resolveBeforeInstantiation
方法中的 InstantiationAwareBeanPostProcessor.postProcessBeforeInstantiation
并未代理bean
的创建,在这里则是由Spring 创建的bean
的时候来调用。
AbstractAutowireCapableBeanFactory#initializeBean()
protected Object initializeBean(String beanName, Object bean, @Nullable RootBeanDefinition mbd) {
// 对特殊的bean进行处理: 实现了Aware、BeanClassLoaderAware、BeanFactoryAware的处理。
if (System.getSecurityManager() != null) {
AccessController.doPrivileged((PrivilegedAction<Object>) () -> {
// 激活Aware方法
invokeAwareMethods(beanName, bean);
return null;
}, getAccessControlContext());
}
else {
invokeAwareMethods(beanName, bean);
}
Object wrappedBean = bean;
// 初始化前
if (mbd == null || !mbd.isSynthetic()) {
// 调用了bean前处理器的方法
wrappedBean = applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName);
}
// 初始化
try {
// 激活自定义的init的方法。
invokeInitMethods(beanName, wrappedBean, mbd);
}
catch (Throwable ex) {
throw new BeanCreationException(
(mbd != null ? mbd.getResourceDescription() : null),
beanName, "Invocation of init method failed", ex);
}
// 初始化后
if (mbd == null || !mbd.isSynthetic()) {
// 调用bean后处理器的方法
wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);
}
return wrappedBean;
}
2.2. postProcessAfterInitialization
BeanPostProcessor.postProcessAfterInitialization
的调用都被封装到 AbstractAutowireCapableBeanFactory#applyBeanPostProcessorsAfterInitialization()
方法中。
而applyBeanPostProcessorsAfterInitialization()
方法的调用在下面三个方法中调用:
AbstractAutowireCapableBeanFactory#resolveBeforeInstantiation
AbstractAutowireCapableBeanFactory#initializeBean(String, Object, RootBeanDefinition)
AbstractAutowireCapableBeanFactory#postProcessObjectFromFactoryBean
2.2.1 resolveBeforeInstantiation
resolveBeforeInstantiation
方法的调用有如下三处:
-
AbstractAutowireCapableBeanFactory#createBean(String, RootBeanDefinition, Object[])
这里的调用实际上就是上面讲的InstantiationAwareBeanPostProcessor.postProcessBeforeInstantiation()
的调用后续,所以这里不再重复 -
AbstractAutowireCapableBeanFactory#getSingletonFactoryBeanForTypeCheck()
-
AbstractAutowireCapableBeanFactory#getNonSingletonFactoryBeanForTypeCheck()
2.2.2 initializeBean
上面介绍 BeanPostProcessor.postProcessBeforeInitialization
的时候已经说了,所以这里不再赘述
2.2.3 postProcessObjectFromFactoryBean
在FactoryBeanRegistrySupport#getObjectFromFactoryBean
中调用,在从FactoryBean
中获取bean
时调用,在此调用可以替换掉FactoryBean
中的返回的bean。
3. SmartInstantiationAwareBeanPostProcessor
SmartInstantiationAwareBeanPostProcessor
在InstantiationAwareBeanPostProcessor
之上又扩展了三个方法,不过我们一般不会使用,所以这里简单叙述一下SmartInstantiationAwareBeanPostProcessor
三个方法的作用
Class<?> predictBeanType(Class<?> beanClass, String beanName)
: 在进行bean
类型匹配时调用,返回值和期望值进行匹配。Constructor<?>[] determineCandidateConstructors(Class<?> beanClass, String beanName)
: 在Spring加载bean
的时候,判断是否需要通过构造注入时,如果返回的值不为空,则进行有参构造注入。
AbstractAutowireCapableBeanFactory#createBeanInstance()
// determineConstructorsFromBeanPostProcessors 中调用了 determineCandidateConstructors 方法,如果ctors != null, 则进行有参构造autowireConstructor
Constructor<?>[] ctors = determineConstructorsFromBeanPostProcessors(beanClass, beanName);
if (ctors != null || mbd.getResolvedAutowireMode() == AUTOWIRE_CONSTRUCTOR ||
mbd.hasConstructorArgumentValues() || !ObjectUtils.isEmpty(args)) {
return autowireConstructor(beanName, mbd, ctors, args);
}
Object getEarlyBeanReference(Object bean, String beanName)
: 在 Spring 解决循环依赖时候使用,返回的值将作为ObjectFactory
的保存的Object
,用于循环依赖的提前暴露。
AbstractAutowireCapableBeanFactory#doCreateBean()
if (earlySingletonExposure) {
if (logger.isTraceEnabled()) {
logger.trace("Eagerly caching bean '" + beanName +
"' to allow for resolving potential circular references");
}
// getEarlyBeanReference 的返回值作为 ObjectFactory 的返回值保存到singletonFactories缓存中
addSingletonFactory(beanName, () -> getEarlyBeanReference(beanName, mbd, bean));
}
以上:内容部分参考
《Spring源码深度解析》
如有侵扰,联系删除。 内容仅用于自我记录学习使用。如有错误,欢迎指正