Spring后置处理器的执行顺序

Spring后置处理器的执行顺序

Spring 提供了多种后置处理器(PostProcessor)扩展点,它们在不同阶段介入容器生命周期。理解它们的执行顺序至关重要。

后置处理器分类

Spring 容器启动
|
├── BeanDefinitionRegistryPostProcessor
│ └── 在 BeanDefinition 加载后,实例化前
│
├── BeanFactoryPostProcessor
│ └── 在 BeanFactory 标准初始化后
│
└── BeanPostProcessor
├── postProcessBeforeInitialization
│ └── 每个 Bean 初始化前
└── postProcessAfterInitialization
└── 每个 Bean 初始化后(AOP 代理创建)

1. BeanDefinitionRegistryPostProcessor

作用

在 BeanDefinition 加载完成后、Bean 实例化之前执行,可以动态注册 BeanDefinition。

典型实现

public interface BeanDefinitionRegistryPostProcessor extends BeanFactoryPostProcessor {
void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry) throws BeansException;
}

重要实现:

  • ConfigurationClassPostProcessor:处理 @Configuration 类
  • MapperScannerConfigurer:MyBatis 扫描 Mapper

执行时机

// AbstractApplicationContext.refresh()
public void refresh() {
// ...

// 1. 调用 BeanDefinitionRegistryPostProcessor
invokeBeanFactoryPostProcessors(beanFactory);

// ...
}

自定义示例

@Component
public class CustomRegistryPostProcessor implements BeanDefinitionRegistryPostProcessor {

@Override
public void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry) {
// 动态注册 Bean
BeanDefinition beanDefinition = BeanDefinitionBuilder
.genericBeanDefinition(MyService.class)
.getBeanDefinition();
registry.registerBeanDefinition("myService", beanDefinition);
}

@Override
public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) {
// 也可以实现 BeanFactoryPostProcessor 的方法
}
}

2. BeanFactoryPostProcessor

作用

在 BeanFactory 标准初始化之后、所有 BeanDefinition 加载完成后执行,可以修改 BeanDefinition 的属性。

典型实现

  • PropertySourcesPlaceholderConfigurer:处理 ${...} 占位符
  • ConfigurationClassPostProcessor:处理 @Configuration

执行顺序

// 1. BeanDefinitionRegistryPostProcessor(按 PriorityOrdered、Ordered 排序)
// 2. BeanDefinitionRegistryPostProcessor(无排序)
// 3. BeanFactoryPostProcessor(按 PriorityOrdered、Ordered 排序)
// 4. BeanFactoryPostProcessor(无排序)

自定义示例

@Component
public class CustomBeanFactoryPostProcessor implements BeanFactoryPostProcessor, Ordered {

@Override
public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) {
// 修改 BeanDefinition
BeanDefinition beanDefinition = beanFactory.getBeanDefinition("dataSource");
beanDefinition.getPropertyValues().add("url", "jdbc:mysql://new-host:3306/db");
}

@Override
public int getOrder() {
return 1; // 数字越小优先级越高
}
}

3. BeanPostProcessor

作用

在每个 Bean 实例化之后、初始化前后执行。

接口定义

public interface BeanPostProcessor {
// 初始化前
@Nullable
default Object postProcessBeforeInitialization(Object bean, String beanName) {
return bean;
}

// 初始化后
@Nullable
default Object postProcessAfterInitialization(Object bean, String beanName) {
return bean;
}
}

典型实现

实现类 作用
AutowiredAnnotationBeanPostProcessor 处理 @Autowired、@Value
CommonAnnotationBeanPostProcessor 处理 @PostConstruct、@PreDestroy、@Resource
AsyncAnnotationBeanPostProcessor 处理 @Async
ScheduledAnnotationBeanPostProcessor 处理 @Scheduled
AbstractAutoProxyCreator 创建 AOP 代理

执行顺序

1. InstantiationAwareBeanPostProcessor.postProcessBeforeInstantiation
2. 实例化 Bean(构造器)
3. InstantiationAwareBeanPostProcessor.postProcessAfterInstantiation
4. 属性赋值(依赖注入)
5. BeanNameAware.setBeanName
6. BeanFactoryAware.setBeanFactory
7. ApplicationContextAware.setApplicationContext
8. BeanPostProcessor.postProcessBeforeInitialization
9. @PostConstruct
10. InitializingBean.afterPropertiesSet
11. init-method
12. BeanPostProcessor.postProcessAfterInitialization(AOP 代理在此创建)

4. InstantiationAwareBeanPostProcessor

作用

在 Bean 实例化前后介入,可以自定义实例化逻辑。

public interface InstantiationAwareBeanPostProcessor extends BeanPostProcessor {
// 实例化前,返回非 null 则跳过默认实例化
default Object postProcessBeforeInstantiation(Class<?> beanClass, String beanName) {
return null;
}

// 实例化后、属性赋值前
default boolean postProcessAfterInstantiation(Object bean, String beanName) {
return true;
}

// 处理属性值
default PropertyValues postProcessProperties(PropertyValues pvs, Object bean, String beanName) {
return null;
}
}

典型实现:

  • AutowiredAnnotationBeanPostProcessor:处理 @Autowired 注入

完整执行顺序图

容器启动
|
v
1. 加载 BeanDefinition
|
v
2. BeanDefinitionRegistryPostProcessor
├── ConfigurationClassPostProcessor(@Configuration)
├── MapperScannerConfigurer(MyBatis)
└── 自定义...
|
v
3. BeanFactoryPostProcessor
├── PropertySourcesPlaceholderConfigurer(${})
└── 自定义...
|
v
4. 注册 BeanPostProcessor
|
v
5. 实例化单例 Bean(逐个)
|
├── 5.1 InstantiationAwareBeanPostProcessor
│ .postProcessBeforeInstantiation()
│
├── 5.2 调用构造器实例化
│
├── 5.3 InstantiationAwareBeanPostProcessor
│ .postProcessAfterInstantiation()
│
├── 5.4 属性赋值(@Autowired 等)
│
├── 5.5 Aware 接口回调
│
├── 5.6 BeanPostProcessor
│ .postProcessBeforeInitialization()
│
├── 5.7 初始化(@PostConstruct, afterPropertiesSet, init-method)
│
├── 5.8 BeanPostProcessor
│ .postProcessAfterInitialization()
│ └── AbstractAutoProxyCreator 创建 AOP 代理
│
v
6. Bean 就绪

自定义后置处理器的顺序控制

实现 Ordered 接口

@Component
public class MyPostProcessor implements BeanPostProcessor, Ordered {

@Override
public int getOrder() {
return Ordered.HIGHEST_PRECEDENCE; // 最高优先级
}
}

使用 @Order 注解

@Component
@Order(1)
public class MyPostProcessor implements BeanPostProcessor {
}

PriorityOrdered vs Ordered

接口 优先级
PriorityOrdered 高于 Ordered
Ordered 普通
无 最低

实际应用

场景1:动态修改 Bean 属性

@Component
public class DataSourceUrlModifier implements BeanFactoryPostProcessor {
@Override
public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) {
String env = System.getProperty("env", "dev");
BeanDefinition bd = beanFactory.getBeanDefinition("dataSource");

if ("prod".equals(env)) {
bd.getPropertyValues().add("url", "jdbc:mysql://prod:3306/db");
}
}
}

场景2:AOP 代理创建

public abstract class AbstractAutoProxyCreator extends ProxyProcessorSupport
implements SmartInstantiationAwareBeanPostProcessor, BeanFactoryAware {

@Override
public Object postProcessAfterInitialization(@Nullable Object bean, String beanName) {
if (bean != null) {
// 检查是否需要代理
return wrapIfNecessary(bean, beanName, cacheKey);
}
return bean;
}
}

场景3:初始化日志

@Component
public class InitializationLogger implements BeanPostProcessor {

@Override
public Object postProcessAfterInitialization(Object bean, String beanName) {
if (beanName.endsWith("Service") || beanName.endsWith("Controller")) {
System.out.println("Initialized: " + beanName);
}
return bean;
}
}

总结

后置处理器 执行时机 用途
BeanDefinitionRegistryPostProcessor BeanDefinition 加载后 动态注册 Bean
BeanFactoryPostProcessor BeanFactory 初始化后 修改 BeanDefinition
InstantiationAwareBeanPostProcessor Bean 实例化前后 自定义实例化、属性注入
BeanPostProcessor Bean 初始化前后 AOP 代理、初始化处理

理解后置处理器的执行顺序,是掌握 Spring 扩展机制的关键。


赏

   转载规则


《Spring后置处理器的执行顺序》 由 小乐 采用 知识共享署名 4.0 国际许可协议 进行许可。
  目录