Spring版本: 5.3.27
JDK版本: 1.8
一、概述
本文来看下Spring中BeanDefinitionRegistryPostProcessor唯一实现,BeanFactoryPostProcessor实现之一的ConfigurationClassPostProcessor。
主要看下ConfigurationClassPostProcessor的作用,以及初探下BeanFactoryPostProcessor。
先上一张ConfigurationClassPostProcessor的类关系图:
BeanDefinitionRegistryPostProcessor继承了BeanFactoryPostProcessor
这种接口继承接口的设计,个人理解是为了扩展功能。那为什么不把BeanDefinitionRegistryPostProcessor的功能直接写到BeanFactoryPostProcessor中呢?这个又涉及到职责分离的原则。
二、功能
1、BeanDefinitionRegistryPostProcessor
java
package org.springframework.beans.factory.support;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.config.BeanFactoryPostProcessor;
/**
* 源码注释翻译:
* BeanDefinitionRegistryPostProcessor是BeanFactoryPostProcessor的扩展,
* 允许在常规的BeanFactoryPostProcessor介入之前注册更多的bean定义信息。
* 特别是,BeanDefinitionRegistryPostProcessor可以注册bean定义信息,这些bean定义信息可能就是
* 定义BeanFactoryPostProcessor实例的。
*/
public interface BeanDefinitionRegistryPostProcessor extends BeanFactoryPostProcessor {
/**
* 源码注释翻译:
* 在标准初始化之后修改应用程序上下文的内部bean定义注册中心(注意这里不是修改bean定义信息)。
* 所有常规的bean定义信息都被加载,但是还没有被实例化。
* 允许在下一个后置处理阶段介入前增加更多的bean定义信息。
*/
void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry) throws BeansException;
}
2、BeanFactoryPostProcessor
java
package org.springframework.beans.factory.config;
import org.springframework.beans.BeansException;
/**
* 源码注释翻译:
* 允许自定义修改容器中bean定义信息的工厂钩子,调整容器中bean的属性值。
*
* 对于想通过自定义配置文件来覆盖容器中的bean属性来说非常有用。类似PropertyResourceConfigurer
* 和其一些具体实现。
*
* BeanFactoryPostProcessor能够修改bean定义信息,但是不能实例化。
* 如果实例化了,可能导致bean过早的实例化,破坏容器并导致意想不到的其他副作用。
* 如果确实需要跟实例化的bean产生交互,可以考虑BeanPostProcessor。
*
* ApplicationContext自动侦测bean定义信息中的BeanFactoryPostProcessor类型的bean,并应用在其他bean被创建前。
* BeanFactoryPostProcessor有可能被ConfigurableApplicationContext以编程方式进行注册。
*
* ApplicationContext中被自动侦测的BeanFactoryPostProcessor类型的bean会根据PriorityOrdered和Ordered被排序。
* 与此形成鲜明对比的是,通过ConfigurableApplicationContext以编程方式注册的bean将按照注册的顺序应用;
* 任何通过实现PriorityOrdered或Ordered接口表达的顺序语义都会被编程注册的后处理器忽略。
*
*/
@FunctionalInterface
public interface BeanFactoryPostProcessor {
/**
* 源码注释翻译:
* 在标准初始化之后修改应用程序上下文的内部bean工厂。
* 所有的bean定义信息都已经被加载,但是还没有实例化。
* 甚至对于急切初始化的bean都可以覆盖和增加属性。
*/
void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException;
}
三、源码分析
refresh方法中的invokeBeanFactoryPostProcessors方法
scss
package org.springframework.context.support;
// ...省略部分代码
final class PostProcessorRegistrationDelegate {
// ...省略部分代码
public static void invokeBeanFactoryPostProcessors(
ConfigurableListableBeanFactory beanFactory, List<BeanFactoryPostProcessor> beanFactoryPostProcessors) {
Set<String> processedBeans = new HashSet<>();
if (beanFactory instanceof BeanDefinitionRegistry) {
BeanDefinitionRegistry registry = (BeanDefinitionRegistry) beanFactory;
List<BeanFactoryPostProcessor> regularPostProcessors = new ArrayList<>();
List<BeanDefinitionRegistryPostProcessor> registryProcessors = new ArrayList<>();
// 这里处理的就是通过编程方式注册的postProcessor
// 如:context.addBeanFactoryPostProcessor
// 可以看出这里没有对注册的postProcessor进行排序
for (BeanFactoryPostProcessor postProcessor : beanFactoryPostProcessors) {
if (postProcessor instanceof BeanDefinitionRegistryPostProcessor) {
BeanDefinitionRegistryPostProcessor registryProcessor =
(BeanDefinitionRegistryPostProcessor) postProcessor;
registryProcessor.postProcessBeanDefinitionRegistry(registry);
registryProcessors.add(registryProcessor);
}
else {
regularPostProcessors.add(postProcessor);
}
}
List<BeanDefinitionRegistryPostProcessor> currentRegistryProcessors = new ArrayList<>();
// 1、调用实现了PriorityOrdered的BeanDefinitionRegistryPostProcessors。
String[] postProcessorNames =
beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);
for (String ppName : postProcessorNames) {
if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) {
currentRegistryProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class));
processedBeans.add(ppName);
}
}
sortPostProcessors(currentRegistryProcessors, beanFactory);
registryProcessors.addAll(currentRegistryProcessors);
invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry, beanFactory.getApplicationStartup());
currentRegistryProcessors.clear();
// 2、调用实现了Ordered的BeanDefinitionRegistryPostProcessors。
postProcessorNames = beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);
for (String ppName : postProcessorNames) {
if (!processedBeans.contains(ppName) && beanFactory.isTypeMatch(ppName, Ordered.class)) {
currentRegistryProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class));
processedBeans.add(ppName);
}
}
sortPostProcessors(currentRegistryProcessors, beanFactory);
registryProcessors.addAll(currentRegistryProcessors);
invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry, beanFactory.getApplicationStartup());
currentRegistryProcessors.clear();
// 3、调用其他所有的BeanDefinitionRegistryPostProcessors,直到没有(这中间有可能会注册新的BeanDefinitionRegistryPostProcessors)
boolean reiterate = true;
while (reiterate) {
reiterate = false;
postProcessorNames = beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);
for (String ppName : postProcessorNames) {
if (!processedBeans.contains(ppName)) {
currentRegistryProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class));
processedBeans.add(ppName);
reiterate = true;
}
}
sortPostProcessors(currentRegistryProcessors, beanFactory);
registryProcessors.addAll(currentRegistryProcessors);
invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry, beanFactory.getApplicationStartup());
currentRegistryProcessors.clear();
}
// 调用截止目前所有的处理器的postProcessBeanFactory
// 因为BeanDefinitionRegistryPostProcessor是继承了BeanFactoryPostProcessor的
// 如果实现中有对beanFactory的修改,这里会进行处理。
invokeBeanFactoryPostProcessors(registryProcessors, beanFactory);
invokeBeanFactoryPostProcessors(regularPostProcessors, beanFactory);
}
else {
// Invoke factory processors registered with the context instance.
invokeBeanFactoryPostProcessors(beanFactoryPostProcessors, beanFactory);
}
String[] postProcessorNames =
beanFactory.getBeanNamesForType(BeanFactoryPostProcessor.class, true, false);
// 区分开实现了PriorityOrdered和Ordered以及剩下的BeanFactoryPostProcessor
// 实现PriorityOrdered
List<BeanFactoryPostProcessor> priorityOrderedPostProcessors = new ArrayList<>();
// 实现Ordered
List<String> orderedPostProcessorNames = new ArrayList<>();
// 剩下的
List<String> nonOrderedPostProcessorNames = new ArrayList<>();
for (String ppName : postProcessorNames) {
if (processedBeans.contains(ppName)) {
// 跳过第一阶段已经处理过的
}
else if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) {
priorityOrderedPostProcessors.add(beanFactory.getBean(ppName, BeanFactoryPostProcessor.class));
}
else if (beanFactory.isTypeMatch(ppName, Ordered.class)) {
orderedPostProcessorNames.add(ppName);
}
else {
nonOrderedPostProcessorNames.add(ppName);
}
}
// 1, 调用实现了PriorityOrdered的BeanFactoryPostProcessor
sortPostProcessors(priorityOrderedPostProcessors, beanFactory);
invokeBeanFactoryPostProcessors(priorityOrderedPostProcessors, beanFactory);
// 2, 调用实现了Ordered的BeanFactoryPostProcessor
List<BeanFactoryPostProcessor> orderedPostProcessors = new ArrayList<>(orderedPostProcessorNames.size());
for (String postProcessorName : orderedPostProcessorNames) {
orderedPostProcessors.add(beanFactory.getBean(postProcessorName, BeanFactoryPostProcessor.class));
}
sortPostProcessors(orderedPostProcessors, beanFactory);
invokeBeanFactoryPostProcessors(orderedPostProcessors, beanFactory);
// 3, 调用其他所有的BeanFactoryPostProcessors.
List<BeanFactoryPostProcessor> nonOrderedPostProcessors = new ArrayList<>(nonOrderedPostProcessorNames.size());
for (String postProcessorName : nonOrderedPostProcessorNames) {
nonOrderedPostProcessors.add(beanFactory.getBean(postProcessorName, BeanFactoryPostProcessor.class));
}
invokeBeanFactoryPostProcessors(nonOrderedPostProcessors, beanFactory);
beanFactory.clearMetadataCache();
}
//...省略部分代码
}
从上面对invokeBeanFactoryPostProcessors方法的分析可以看出,ConfigurationClassPostProcessor会在46及83行被处理。
46行:
invokeBeanDefinitionRegistryPostProcessors方法中会调用具体处理器的postProcessBeanDefinitionRegistry方法。
ConfigurationClassPostProcessor中的postProcessBeanDefinitionRegistry方法会从配置类中分析出更多的bean定义信息注册到容器中。
83行
invokeBeanFactoryPostProcessors方法中会调用具体处理器的postProcessBeanFactory方法。
ConfigurationClassPostProcessor中的postProcessBeanFactory方法会将配置类通过CGLIB增强并替换原有的配置类,并在容器中新增了一个bean后置处理器。
四、自定义
java
package com.lazy.snail;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
import org.springframework.beans.factory.support.BeanDefinitionRegistry;
import org.springframework.beans.factory.support.BeanDefinitionRegistryPostProcessor;
import org.springframework.core.PriorityOrdered;
public class MyConfigPostProcessor implements BeanDefinitionRegistryPostProcessor, PriorityOrdered {
@Override
public void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry) throws BeansException {
System.out.println("我拿到了注册器,可以新增bean定义信息了");
}
@Override
public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
System.out.println("容器在手,天下我有");
}
@Override
public int getOrder() {
return 0;
}
}
java
package com.lazy.snail;
import lombok.extern.slf4j.Slf4j;
import org.junit.jupiter.api.Test;
import org.springframework.context.ConfigurableApplicationContext;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
@Slf4j
public class SpringTest {
@Test
void test() {
ConfigurableApplicationContext context = new AnnotationConfigApplicationContext();
context.addBeanFactoryPostProcessor(new MyConfigPostProcessor());
context.refresh();
}
}
五、小结
-
BeanFactoryPostProcessor
的职责:- 主要针对已经存在的
BeanDefinition
进行修改,即:它在 Spring 容器启动时,BeanFactory
中所有的 Bean 定义信息已经加载进来之后,允许开发者通过BeanFactoryPostProcessor
对这些 Bean 定义 进行修改或增强。 - 例如,可以修改 Bean 的属性值、作用域等元数据,影响后续 Bean 的实例化过程。
- 主要针对已经存在的
-
BeanDefinitionRegistryPostProcessor
的职责:- 主要是扩展
BeanDefinition
的注册阶段,它允许在 Spring 注册 Bean 定义信息之前 ,向容器中动态地 注册新的 Bean 定义信息 。它不仅能像BeanFactoryPostProcessor
那样修改已经存在的 Bean 定义,还可以直接注册新的BeanDefinition
。 - 例如,可以通过实现
BeanDefinitionRegistryPostProcessor
,动态地向BeanDefinitionRegistry
中注册额外的BeanDefinition
,这通常用于一些框架级的扩展,比如 Spring Boot 的自动配置机制。
- 主要是扩展