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 国际许可协议 进行许可。
  目录