在 Spring 容器的 refresh() 过程中,registerBeanPostProcessors(beanFactory) 负责从容器中找出所有实现了 BeanPostProcessor 接口的类,实例化它们,并按顺序注册到 BeanFactory 中。这些 BeanPostProcessor 将在后续 Bean 实例化 和 初始化 的生命周期中被调用,允许我们在 Bean 初始化前后对 Bean 实例进行增强(例如 AOP 代理、属性注入等)。
1. 方法调用入口
registerBeanPostProcessors(beanFactory) 定义在 AbstractApplicationContext 中,位于 refresh() 方法内:
java
// AbstractApplicationContext.java
@Override
public void refresh() throws BeansException, IllegalStateException {
synchronized (this.startupShutdownMonitor) {
// ...
// 调用 BeanFactoryPostProcessor(修改 BeanDefinition)
invokeBeanFactoryPostProcessors(beanFactory);
// 注册 BeanPostProcessor(此时尚未实例化普通单例 Bean)
registerBeanPostProcessors(beanFactory);
// ... 国际化、事件监听器等初始化
// 实例化所有单例 Bean(非懒加载)
finishBeanFactoryInitialization(beanFactory);
}
}
此时,所有的 BeanDefinition 已经加载完毕(可能已被 BeanFactoryPostProcessor 修改),但普通单例 Bean 尚未实例化。BeanPostProcessor 需要提前实例化并注册到 BeanFactory 中,以便在后续 Bean 实例化过程中能够立即生效。
2. 实际执行委托
AbstractApplicationContext 并未直接实现注册逻辑,而是委托给 PostProcessorRegistrationDelegate 的静态方法:
java
// AbstractApplicationContext.java
protected void registerBeanPostProcessors(ConfigurableListableBeanFactory beanFactory) {
PostProcessorRegistrationDelegate.registerBeanPostProcessors(beanFactory, this);
}
-
beanFactory:当前容器的ConfigurableListableBeanFactory(通常是DefaultListableBeanFactory)。 -
this:ApplicationContext本身,用于添加ApplicationListener(某些BeanPostProcessor可能也是监听器)。
3. PostProcessorRegistrationDelegate.registerBeanPostProcessors 核心源码解析
3.1 整体流程
java
public static void registerBeanPostProcessors(
ConfigurableListableBeanFactory beanFactory, AbstractApplicationContext applicationContext) {
// 1. 获取容器中所有类型为 BeanPostProcessor 的 Bean 名称
String[] postProcessorNames = beanFactory.getBeanNamesForType(BeanPostProcessor.class, true, false);
// 2. 统计容器中已存在的 BeanPostProcessor 数量(用于后续日志输出)
int beanProcessorTargetCount = beanFactory.getBeanPostProcessorCount() + 1 + postProcessorNames.length;
beanFactory.addBeanPostProcessor(new BeanPostProcessorChecker(beanFactory, beanProcessorTargetCount));
// 3. 按优先级分组:PriorityOrdered、Ordered、无顺序
List<BeanPostProcessor> priorityOrderedPostProcessors = new ArrayList<>();
List<BeanPostProcessor> internalPostProcessors = new ArrayList<>();
List<String> orderedPostProcessorNames = new ArrayList<>();
List<String> nonOrderedPostProcessorNames = new ArrayList<>();
for (String ppName : postProcessorNames) {
if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) {
BeanPostProcessor pp = beanFactory.getBean(ppName, BeanPostProcessor.class);
priorityOrderedPostProcessors.add(pp);
// 同时检查是否为 MergedBeanDefinitionPostProcessor(Spring 内部特殊处理)
if (pp instanceof MergedBeanDefinitionPostProcessor) {
internalPostProcessors.add(pp);
}
} else if (beanFactory.isTypeMatch(ppName, Ordered.class)) {
orderedPostProcessorNames.add(ppName);
} else {
nonOrderedPostProcessorNames.add(ppName);
}
}
// 4. 排序并注册 PriorityOrdered 组
sortPostProcessors(priorityOrderedPostProcessors, beanFactory);
registerBeanPostProcessors(beanFactory, priorityOrderedPostProcessors);
// 5. 排序并注册 Ordered 组
List<BeanPostProcessor> orderedPostProcessors = new ArrayList<>();
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);
// 6. 注册无优先级组(普通)
List<BeanPostProcessor> nonOrderedPostProcessors = new ArrayList<>();
for (String ppName : nonOrderedPostProcessorNames) {
BeanPostProcessor pp = beanFactory.getBean(ppName, BeanPostProcessor.class);
nonOrderedPostProcessors.add(pp);
if (pp instanceof MergedBeanDefinitionPostProcessor) {
internalPostProcessors.add(pp);
}
}
registerBeanPostProcessors(beanFactory, nonOrderedPostProcessors);
// 7. 重新排序并注册 internalPostProcessors(MergedBeanDefinitionPostProcessor 通常需要最后注册)
sortPostProcessors(internalPostProcessors, beanFactory);
registerBeanPostProcessors(beanFactory, internalPostProcessors);
// 8. 将 BeanPostProcessor 中实现了 ApplicationListener 的添加到应用上下文的事件监听器列表
beanFactory.addBeanPostProcessor(new ApplicationListenerDetector(applicationContext));
}
3.2 关键步骤说明
-
获取所有
BeanPostProcessor的 Bean 名称通过
beanFactory.getBeanNamesForType(BeanPostProcessor.class, true, false)获取当前容器中定义的所有BeanPostProcessor类型的 Bean 名称。注意此时这些 Bean 尚未实例化(只是BeanDefinition存在)。 -
添加一个
BeanPostProcessorChecker这是一个内部辅助处理器,用于在日志中输出
BeanPostProcessor实例化过程中的警告信息(例如某些BeanPostProcessor未能被正确注册),不影响主要逻辑。 -
按优先级分组
-
PriorityOrdered:最高优先级,需要先被注册(先注册的会先执行)。 -
Ordered:次高优先级。 -
普通:无优先级,最后注册。
同时,如果某个
BeanPostProcessor还实现了MergedBeanDefinitionPostProcessor子接口,则将其单独放入internalPostProcessors集合中,稍后统一处理(因为MergedBeanDefinitionPostProcessor通常需要在普通处理器之后执行,用于合并 Bean 定义信息,例如AutowiredAnnotationBeanPostProcessor)。
-
-
实例化并注册
对于每一组,通过
beanFactory.getBean(ppName, BeanPostProcessor.class)立即实例化 该BeanPostProcessor(这会触发其依赖的 Bean 的创建)。然后将实例化后的对象添加到BeanFactory的BeanPostProcessor列表中(调用beanFactory.addBeanPostProcessor(pp))。注意 :
BeanPostProcessor的实例化会提前发生,因此编写BeanPostProcessor时应当避免依赖其他普通 Bean,否则可能导致提前创建那些 Bean,引发循环依赖或状态不一致问题。 -
排序
使用
sortPostProcessors方法,内部通过AnnotationAwareOrderComparator实现,支持Ordered接口和@Order注解。 -
internalPostProcessors的特殊处理因为
MergedBeanDefinitionPostProcessor需要处理所有 Bean 的合并 Bean 定义(通常在postProcessMergedBeanDefinition阶段),Spring 将它们单独分组并最后注册 ,以确保它们在其他普通BeanPostProcessor之后才被添加到列表中。不过实际执行顺序仍受BeanFactory中BeanPostProcessor列表顺序的影响。 -
ApplicationListenerDetector最后,Spring 还会添加一个特殊的
BeanPostProcessor:ApplicationListenerDetector,它负责在 Bean 初始化后检测该 Bean 是否实现了ApplicationListener,如果是,则自动将其注册到应用上下文的事件广播器中。这个处理器必须最后注册,以确保它能处理所有其他处理器。
4. registerBeanPostProcessors 辅助方法
java
private static void registerBeanPostProcessors(
ConfigurableListableBeanFactory beanFactory, List<BeanPostProcessor> postProcessors) {
for (BeanPostProcessor postProcessor : postProcessors) {
beanFactory.addBeanPostProcessor(postProcessor);
}
}
ConfigurableListableBeanFactory 的实现类(如 AbstractBeanFactory)内部维护了一个 List<BeanPostProcessor>,每当调用 addBeanPostProcessor 时,新的处理器会被追加到列表尾部。后续创建 Bean 时,会依次 调用列表中的所有 BeanPostProcessor。
5. BeanPostProcessor 的执行时机
注册完成后,在 refresh() 后续的 finishBeanFactoryInitialization(beanFactory) 方法中,当容器实例化每个单例 Bean 时,会按照注册顺序依次调用每个 BeanPostProcessor 的两个方法:
-
postProcessBeforeInitialization(Object bean, String beanName):在 Bean 的初始化方法(如@PostConstruct、afterPropertiesSet、自定义init-method)之前调用。 -
postProcessAfterInitialization(Object bean, String beanName):在初始化方法之后调用。
此外,MergedBeanDefinitionPostProcessor 会在 Bean 实例化之前调用 postProcessMergedBeanDefinition 方法,用于处理合并后的 RootBeanDefinition。
6. 与 BeanFactoryPostProcessor 的区别
| 特性 | BeanFactoryPostProcessor |
BeanPostProcessor |
|---|---|---|
| 执行阶段 | Bean 定义加载之后,Bean 实例化之前 | Bean 实例化之后,初始化前后 |
| 主要作用 | 修改 BeanDefinition 元数据 |
修改或增强 Bean 实例(如代理、属性注入) |
| 典型示例 | PropertySourcesPlaceholderConfigurer、ConfigurationClassPostProcessor |
AutowiredAnnotationBeanPostProcessor、ApplicationContextAwareProcessor |
| 执行次数 | 全局一次 | 每个 Bean 创建时都会执行 |
| 注册方式 | 通过 invokeBeanFactoryPostProcessors 调用,可动态注册新 Bean 定义 |
通过 registerBeanPostProcessors 注册到 BeanFactory 列表 |
7. 注意事项与最佳实践
-
不要依赖普通 Bean :
BeanPostProcessor的实例化发生在容器启动早期,如果它依赖了其他普通 Bean(通过@Autowired等),会导致那些 Bean 被提前创建,可能引发循环依赖或出乎意料的副作用。 -
优先级选择 :如果多个
BeanPostProcessor对同一个 Bean 进行增强,需要留意执行顺序。通常可以使用PriorityOrdered或Ordered接口来控制。 -
线程安全 :
BeanPostProcessor实例会被所有 Bean 的创建过程共享,因此实现应该是线程安全的。 -
性能 :
BeanPostProcessor会对容器中每个 Bean 的创建过程产生影响,因此应避免在其中执行耗时操作。
8. 总结
registerBeanPostProcessors(beanFactory) 是 Spring 容器启动过程中的一个重要步骤,它负责从容器中找出所有 BeanPostProcessor 类,实例化它们 并按优先级排序后注册到 BeanFactory 的内部列表中。这些处理器后续会参与到每个 Bean 的创建过程中,为 Spring 提供 AOP、依赖注入、上下文感知等核心功能。理解这个过程对于开发自定义 BeanPostProcessor 以及排查容器启动问题具有重要意义。