这次的内容是上图中的第06步。
前言
通过前面几篇文章的介绍,在整个容器刷新过程中现在已经有了如下组件:
先来看看前面几篇文章都做了什么:
`01-prepareRefresh()`: `earlyApplicationListeners`、`applicationListeners` 、`initPropertySources()`、`validateRequiredProperties`
`02-obtainFreshBeanFactory()`: `refreshBeanFactory`
`03-prepareBeanFactory()`: `ignoreDependencyInterface`、`setBeanExpressionResolver`、`registerResolvableDependency`、`Environment`
`04-postProcessBeanFactory()`: 具体实现类的特殊逻辑(`Servlet` 等)
`05-invokeBeanFactoryPostProcessors()`: 可能发生的对 `BeanFactory/BeanDefinitionRegistry` 的修改操作
也就是说,现在的 BeanFactory 已经完全准备好了,通过正常途径已经无法修改 BeanFactory 了。
接下来就要开始考虑单例 Bean 的初始化了,但是在此之前,还有好多的准备工作。
第一个准备工作就是本文要说的 registerBeanPostProcessors()。
registerBeanPostProcessors() 只是注册各种 BeanPostProcessor,还远远没到 BeanPostProcessor 执行的时候。
前置知识
看 registerBeanPostProcessors() 方法的名字就是要注册 BeanPostProcessor 了,那么先来了解一下 BeanPostProcessor 是什么。
BeanPostProcessor 是一个钩子函数,用来修改新创建的 Bean 实例,比如 检测标记在 Bean 上的标记接口或用代理对象包装 Bean。BeanPostProcessor 还有一系列的扩展子接口。
下面就介绍几种常见的 BeanPostProcessor。
BeanPostProcessor
public interface BeanPostProcessor {
/**
* 在任何 「Bean初始化方法」(比如说InitializingBean#afterPropertiesSet) 回调之前, 将该 BeanPostProcessor 应用于一个给定的新的Bean实例.
*
* 此处传入的 Bean 已经经过 populateBean 填充属性了.
* 返回的 bean 实例可能是对原始bean的包装.
* 默认实现: 原样返回给定的 Bean
*
* 如果返回 null, 则不会调用后续的 BeanPostProcessors.
*
* @return 原始对象或者对原始对象的包装;
*/
@Nullable
default Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
return bean;
}
/**
* 在任何 「Bean初始化方法」(比如说InitializingBean#afterPropertiesSet) 回调之后, 将该 BeanPostProcessor 应用于一个给定的新的Bean实例.
*
* 此处传入的 Bean 已经经过 populateBean 填充属性了.
* 返回的 bean 实例可能是对原始bean的包装.
*
* 对于 FactoryBean 的情况而言,该回调方法既可以对 FactoryBean 实例本身回调, 也可以对 FactoryBean 返回的对象回调(从 Spring 2.0 开始).
* 具体实现可以自己决定是否回调 FactoryBean 实例 或/和 FactoryBean 返回的实例.
*
* 与其他的回调方法不同, 该回调方法也可以被 InstantiationAwareBeanPostProcessor#postProcessBeforeInstantiation 触发
*
* 默认实现: 原样返回给定的 Bean
*
* 如果返回 null, 则不会调用后续的 BeanPostProcessors.
*
* @return 原始对象或者对原始对象的包装;
*/
@Nullable
default Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
return bean;
}
}
InstantiationAwareBeanPostProcessor
InstantiationAwareBeanPostProcessor 是 BeanPostProcessor 的子接口,主要扩展了如下的方法:
- 扩展了一个在 Bean 实例化 之前的回调
- 扩展了一个在 Bean 实例化 之后, 但在 Bean 填充属性或自动装配发生之前的回调
一般用于拦截特定目标对象的默认实例化,比如创建(池化、懒加载等)代理对象。或者实现特定的注入策略,比如字段注入。
该接口是一个特殊接口,主要在框架内部使用。一般场景,建议尽可能实现简单的 BeanPostProcessor 接口。而不是使用该接口。
public interface InstantiationAwareBeanPostProcessor extends BeanPostProcessor {
/**
* 在目标bean实例化之前回调该BeanPostProcessor.
*
* 返回的bean对象可能是代理对象,而不是目标bean,从而拦截了目标bean的默认实例化.
*
* 如果该方法返回了非空对象,则当前bean的创建过程将被短路.
* 短路之后唯一会被进一步调用的是来自BeanPostProcessors的postProcessAfterInitialization方法。
*
* 默认实现: 返回 null
*
* @return 代理对象 或 返回null以继续Bean的默认实例化流程
*/
@Nullable
default Object postProcessBeforeInstantiation(Class<?> beanClass, String beanName) throws BeansException {
return null;
}
/**
* 回调时机: Bean 被[实例化]之后(构造器或工厂方法),但在spring填充属性或自动装配之前
*
* 这里是实现用户自定义字段注入的完美时机,刚好在 spring 的自动注入之前.
*
* 默认实现: return true
*
* @return true: 表示应该给当前Bean填充属性;
* false: 对当前Bean的属性填充应该被跳过;
*
* 返回false还会阻止在当前bean实例上回调任何后续的InstantiationAwareBeanPostProcessor实例。
*/
default boolean postProcessAfterInstantiation(Object bean, String beanName) throws BeansException {
return true;
}
/**
* 在工厂将给定的属性值应用于给定的bean之前,对当前Bean进行处理
*
* 如果具体实现类提供来自定义的postProcessPropertyValues实现,则应返回null(默认值),否则返回pvs
*
* @return the actual property values to apply to the given bean (can be the passed-in
* PropertyValues instance), or {@code null} which proceeds with the existing properties
* but specifically continues with a call to {@link #postProcessPropertyValues}
* (requiring initialized {@code PropertyDescriptor}s for the current bean class)
*/
@Nullable
default PropertyValues postProcessProperties(PropertyValues pvs, Object bean, String beanName)
throws BeansException {
return null;
}
/**
* Post-process the given property values before the factory applies them
* to the given bean. Allows for checking whether all dependencies have been
* satisfied, for example based on a "Required" annotation on bean property setters.
* <p>Also allows for replacing the property values to apply, typically through
* creating a new MutablePropertyValues instance based on the original PropertyValues,
* adding or removing specific values.
* <p>The default implementation returns the given {@code pvs} as-is.
* @param pvs the property values that the factory is about to apply (never {@code null})
* @param pds the relevant property descriptors for the target bean (with ignored
* dependency types - which the factory handles specifically - already filtered out)
* @param bean the bean instance created, but whose properties have not yet been set
* @param beanName the name of the bean
* @return the actual property values to apply to the given bean (can be the passed-in
* PropertyValues instance), or {@code null} to skip property population
* @throws org.springframework.beans.BeansException in case of errors
* @see #postProcessProperties
* @see org.springframework.beans.MutablePropertyValues
* @deprecated as of 5.1, in favor of {@link #postProcessProperties(PropertyValues, Object, String)}
*/
@Deprecated
@Nullable
default PropertyValues postProcessPropertyValues(
PropertyValues pvs, PropertyDescriptor[] pds, Object bean, String beanName) throws BeansException {
return pvs;
}
}
DestructionAwareBeanPostProcessor
DestructionAwareBeanPostProcessor 是 Bean 被销毁之前的回调接口。所谓的销毁指的是: DisposableBean.destroy()、 destroy-method 等。
public interface DestructionAwareBeanPostProcessor extends BeanPostProcessor {
/**
* Bean 被销毁之前回调
*/
void postProcessBeforeDestruction(Object bean, String beanName) throws BeansException;
/**
* 当前 Bean 是否需要被销毁
* @since 4.3
*/
default boolean requiresDestruction(Object bean) {
return true;
}
}
registerBeanPostProcessors
这一步就是给 BeanFactory 中注册各种 BeanPostProcessor,那么最终注册到哪里去了呢?
addBeanPostProcessor
看看下面的 addBeanPostProcessors() 和 addBeanPostProcessor() 方法就明白了。
值得注意的是,这两个方法虽然名字看起来是 add,但是实际上他的作用应该是: removeAndAddToLast 的意思,就是每次先删掉之前的,再将新增的放到最后。
public abstract class AbstractBeanFactory extends FactoryBeanRegistrySupport implements ConfigurableBeanFactory {
private final List<BeanPostProcessor> beanPostProcessors = new BeanPostProcessorCacheAwareList();
public void addBeanPostProcessors(Collection<? extends BeanPostProcessor> beanPostProcessors) {
this.beanPostProcessors.removeAll(beanPostProcessors);
this.beanPostProcessors.addAll(beanPostProcessors);
}
@Override
public void addBeanPostProcessor(BeanPostProcessor beanPostProcessor) {
Assert.notNull(beanPostProcessor, "BeanPostProcessor must not be null");
// Remove from old position, if any
this.beanPostProcessors.remove(beanPostProcessor);
// Add to end of list
this.beanPostProcessors.add(beanPostProcessor);
}
}
继续看 registerBeanPostProcessors(),实际上最终是委托给了 PostProcessorRegistrationDelegate.registerBeanPostProcessors(ConfigurableListableBeanFactory, AbstractApplicationContext) 这个工具方法。
源码流程
方法刚开始还是和上一篇介绍的 invokeBeanFactoryPostProcessors 一样,来了一大波提示信息,大概意思是:
这个方法看起来写的很啰嗦,好像很容易优化。但是在你优化之前先瞅瞅 github 已经被拒绝的的 PR 列表……
final class PostProcessorRegistrationDelegate {
public static void registerBeanPostProcessors(
ConfigurableListableBeanFactory beanFactory, AbstractApplicationContext applicationContext) {
// WARNING: Although it may appear that the body of this method can be easily
// refactored to avoid the use of multiple loops and multiple lists, the use
// of multiple lists and multiple passes over the names of processors is
// intentional. We must ensure that we honor the contracts for PriorityOrdered
// and Ordered processors. Specifically, we must NOT cause processors to be
// instantiated (via getBean() invocations) or registered in the ApplicationContext
// in the wrong order.
//
// Before submitting a pull request (PR) to change this method, please review the
// list of all declined PRs involving changes to PostProcessorRegistrationDelegate
// to ensure that your proposal does not result in a breaking change:
// https://github.com/spring-projects/spring-framework/issues?q=PostProcessorRegistrationDelegate+is%3Aclosed+label%3A%22status%3A+declined%22
// 这里依然是小心翼翼仅仅获取了 BeanPostProcessor 类型的 beanName,还不能调用 getBean()
String[] postProcessorNames = beanFactory.getBeanNamesForType(BeanPostProcessor.class, true, false);
// Register BeanPostProcessorChecker that logs an info message when
// a bean is created during BeanPostProcessor instantiation, i.e. when
// a bean is not eligible for getting processed by all BeanPostProcessors.
// beanFactory.getBeanPostProcessorCount(): 当前 BeanFactory 中已经存在的 BeanPostProcessor 数量
// +1: 加的 1 就是 `BeanPostProcessorChecker` 自己
// postProcessorNames.length: 指的是在下面一大波循环中要新增到 BeanFactory 中的 BeanPostProcessor
int beanProcessorTargetCount = beanFactory.getBeanPostProcessorCount() + 1 + postProcessorNames.length;
// BeanPostProcessorChecker就是来检测: 在 BeanPostProcessor 初始化的过程中有没有导致普通的 Bean 初始化
// 如果有: 就打印一堆信息提醒你, 有 Bean 被过早初始化了
// 为什么要提醒: 因为现在还在创建 BeanPostProcessor,
// 但是这个过程中你突然创建了一个普通 Bean,
// 那么你这个过早被创建的普通 Bean 可能无法被 BeanPostProcessor 增强(比较 BeanPostProcessor 自己都还在创建过程中呢)
beanFactory.addBeanPostProcessor(new BeanPostProcessorChecker(beanFactory, beanProcessorTargetCount));
// 还是老套路: 将 BeanPostProcessor 分类(4大类)
// 需要注意的是第1类和第2类是通过 getBean 创建出来的实例,其他两类都是 beanName(避免过早实例化)
// 需要注意的是第1类和第2类是通过 getBean 创建出来的实例,其他两类都是 beanName(避免过早实例化)
// 需要注意的是第1类和第2类是通过 getBean 创建出来的实例,其他两类都是 beanName(避免过早实例化)
// Separate between BeanPostProcessors that implement PriorityOrdered,
// Ordered, and the rest.
// 第 1 类: 实现了 PriorityOrdered 接口的
List<BeanPostProcessor> priorityOrderedPostProcessors = new ArrayList<>();
// 实现了 `PriorityOrdered` 接口的 BeanPostProcessor 还有个细分的类型
// 第 2 类: MergedBeanDefinitionPostProcessor 类型的 BeanPostProcessor
List<BeanPostProcessor> internalPostProcessors = new ArrayList<>();
// 第 3 类: 实现了 Ordered 接口的
List<String> orderedPostProcessorNames = new ArrayList<>();
// 第 4 类: 普通的 BeanPostProcessor
List<String> nonOrderedPostProcessorNames = new ArrayList<>();
for (String ppName : postProcessorNames) {
// 第 1 类
if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) {
// 这里是通过 getBean 真真正正创建了 BeanPostProcessor 类型的 Bean
// 而不是 beanName
BeanPostProcessor pp = beanFactory.getBean(ppName, BeanPostProcessor.class);
priorityOrderedPostProcessors.add(pp);
// 第 2 类
if (pp instanceof MergedBeanDefinitionPostProcessor) {
internalPostProcessors.add(pp);
}
}
// 第 3 类
else if (beanFactory.isTypeMatch(ppName, Ordered.class)) {
orderedPostProcessorNames.add(ppName);
}
// 第 4 类
else {
nonOrderedPostProcessorNames.add(ppName);
}
}
// 经过上面的循环,已经给各种 BeanPostProcessor 分好类了
// 下面就是按照不同类型的优先级注册到 BeanPostProcessor 中
// 1. 先注册实现了 `PriorityOrdered` 接口的 BeanPostProcessor
// First, register the BeanPostProcessors that implement PriorityOrdered.
sortPostProcessors(priorityOrderedPostProcessors, beanFactory);
// 其实就是调用了 beanFactory.addBeanPostProcessor 给当前 BeanFactory 中新增 BeanPostProcessor
// 作用是: 将给定的 BeanPostProcessor 添加到最后
registerBeanPostProcessors(beanFactory, priorityOrderedPostProcessors);
// 2. 注册实现了 `Ordered` 接口的 BeanPostProcessor
// Next, register the BeanPostProcessors that implement Ordered.
// 先通过 getBean 创建实例,然后注册
List<BeanPostProcessor> orderedPostProcessors = new ArrayList<>(orderedPostProcessorNames.size());
for (String ppName : orderedPostProcessorNames) {
BeanPostProcessor pp = beanFactory.getBean(ppName, BeanPostProcessor.class);
orderedPostProcessors.add(pp);
if (pp instanceof MergedBeanDefinitionPostProcessor) {
internalPostProcessors.add(pp);
}
}
sortPostProcessors(orderedPostProcessors, beanFactory);
registerBeanPostProcessors(beanFactory, orderedPostProcessors);
// 3. 普通的 BeanPostProcessor
// Now, register all regular BeanPostProcessors.
// 先通过 getBean 创建实例,然后注册
List<BeanPostProcessor> nonOrderedPostProcessors = new ArrayList<>(nonOrderedPostProcessorNames.size());
for (String ppName : nonOrderedPostProcessorNames) {
BeanPostProcessor pp = beanFactory.getBean(ppName, BeanPostProcessor.class);
nonOrderedPostProcessors.add(pp);
if (pp instanceof MergedBeanDefinitionPostProcessor) {
internalPostProcessors.add(pp);
}
}
registerBeanPostProcessors(beanFactory, nonOrderedPostProcessors);
// 4. 注册 internalPostProcessors
// 所谓的 `internalPostProcessors` 指的就是 `MergedBeanDefinitionPostProcessor` 这种子接口
// Finally, re-register all internal BeanPostProcessors.
sortPostProcessors(internalPostProcessors, beanFactory);
registerBeanPostProcessors(beanFactory, internalPostProcessors);
// 5. 将 `ApplicationListenerDetector` 移动到最后
// 就是来处理实现了 `ApplicationListener` 这种事件接口的 Bean 的
// Re-register post-processor for detecting inner beans as ApplicationListeners,
// moving it to the end of the processor chain (for picking up proxies etc).
beanFactory.addBeanPostProcessor(new ApplicationListenerDetector(applicationContext));
}
}
BeanPostProcessorChecker
现在回头再看看 BeanPostProcessorChecker。他是用来检测:在 BeanPostProcessor 的初始化过程中是不是有其他普通的 Bean 被过早初始化了。
- 什么叫普通的 Bean: 除了 BeanPostProcessor 类型和 BeanDefinition.role == RootBeanDefinition.ROLE_INFRASTRUCTURE 的 Bean 都是普通 Bean
- 什么叫过早初始化: 一个普通 Bean 的正常创建流程应该经过一系列的 BeanPostProcessor 处理,但是现在 BeanPostProcessor 自己还在初始化过程中呢。这时候如果初始化一个普通的 Bean ,就无法保证这个普通 Bean 被所有的 BeanPostProcessor 处理,也就是说 Bean 被提前初始化了。
成员变量 beanPostProcessorTargetCount 什么意思呢?
其实就是上面代码中的 int beanProcessorTargetCount = beanFactory.getBeanPostProcessorCount() + 1 + postProcessorNames.length; 这一行。
- beanFactory.getBeanPostProcessorCount(): 指的是 BeanFactory 中已经存在的 BeanPostProcessor 实例的个数
- +1: 指的是 BeanPostProcessorChecker 自己
- postProcessorNames.length: 指的是经过上面的几波循环之后新增了多少 BeanPostProcessor 的实例
private static final class BeanPostProcessorChecker implements BeanPostProcessor {
private static final Log logger = LogFactory.getLog(BeanPostProcessorChecker.class);
private final ConfigurableListableBeanFactory beanFactory;
private final int beanPostProcessorTargetCount;
public BeanPostProcessorChecker(ConfigurableListableBeanFactory beanFactory, int beanPostProcessorTargetCount) {
this.beanFactory = beanFactory;
this.beanPostProcessorTargetCount = beanPostProcessorTargetCount;
}
@Override
public Object postProcessBeforeInitialization(Object bean, String beanName) {
return bean;
}
@Override
public Object postProcessAfterInitialization(Object bean, String beanName) {
// 除了 BeanPostProcessor 类型 和 BeanDefinition.role == `RootBeanDefinition.ROLE_INFRASTRUCTURE`
if (!(bean instanceof BeanPostProcessor) && !isInfrastructureBean(beanName) &&
// 这个小于判断如果成立的话 就说明现在还有 `BeanPostProcessor` 没有实例化完成
this.beanFactory.getBeanPostProcessorCount() < this.beanPostProcessorTargetCount) {
if (logger.isInfoEnabled()) {
logger.info("Bean '" + beanName + "' of type [" + bean.getClass().getName() +
"] is not eligible for getting processed by all BeanPostProcessors " +
"(for example: not eligible for auto-proxying)");
}
}
return bean;
}
private boolean isInfrastructureBean(@Nullable String beanName) {
if (beanName != null && this.beanFactory.containsBeanDefinition(beanName)) {
BeanDefinition bd = this.beanFactory.getBeanDefinition(beanName);
return (bd.getRole() == RootBeanDefinition.ROLE_INFRASTRUCTURE);
}
return false;
}
}
小节
通过这一步,所有的 BeanPostProcessor 的实例已经被创建了。并且都被注册到了 BeanFactory 中了。
但是需要注意的是,这里仅仅是 BeanPostProcessor 自己的实例化和注册,还没到 BeanPostProcessor 执行的时候呢。
后续的 Bean 创建过程中,这些 BeanPostProcessor 就可以发挥作用了。