Spring后置处理器详解
后置处理器概述
在Spring框架中,后置处理器(Post Processor)是一种扩展机制,允许开发者在Bean创建和容器初始化的不同阶段介入,对Bean定义或Bean实例进行自定义处理。
Spring提供了三个核心后置处理器接口,它们在容器生命周期的不同阶段发挥作用:
graph TB
subgraph Spring后置处理器体系
A[BeanDefinitionRegistryPostProcessor<br/>Bean定义注册后置处理器]
B[BeanFactoryPostProcessor<br/>Bean工厂后置处理器]
C[BeanPostProcessor<br/>Bean后置处理器]
end
A -->|继承| B
B -.->|作用时机不同| C
style A fill:#e74c3c,stroke:#c0392b,color:#fff,rx:10,ry:10
style B fill:#3498db,stroke:#2980b9,color:#fff,rx:10,ry:10
style C fill:#2ecc71,stroke:#27ae60,color:#fff,rx:10,ry:10三者的核心区别
| 处理器类型 | 作用阶段 | 操作对象 | 典型用途 |
|---|---|---|---|
| BeanDefinitionRegistryPostProcessor | Bean定义加载后,实例化前 | BeanDefinition注册表 | 动态注册新的Bean定义 |
| BeanFactoryPostProcessor | Bean定义加载后,实例化前 | BeanDefinition属性 | 修改Bean定义的属性值 |
| BeanPostProcessor | Bean实例化后,初始化前后 | Bean实例 | 包装/增强Bean实例 |
执行时序
sequenceDiagram
participant Container as Spring容器
participant BDRPP as BeanDefinitionRegistry<br/>PostProcessor
participant BFPP as BeanFactory<br/>PostProcessor
participant BPP as BeanPostProcessor
participant Bean as Bean实例
Container->>Container: 加载Bean定义
Container->>BDRPP: postProcessBeanDefinitionRegistry()
Note over BDRPP: 可以注册新的Bean定义
Container->>BFPP: postProcessBeanFactory()
Note over BFPP: 可以修改Bean定义属性
Container->>Bean: 实例化Bean
Container->>BPP: postProcessBeforeInitialization()
Container->>Bean: 初始化Bean(@PostConstruct等)
Container->>BPP: postProcessAfterInitialization()
Note over BPP: 可以返回代理对象BeanDefinitionRegistryPostProcessor详解
接口定义
BeanDefinitionRegistryPostProcessor继承自BeanFactoryPostProcessor,是Spring中最早执行的后置处理器。
public interface BeanDefinitionRegistryPostProcessor
extends BeanFactoryPostProcessor {
/**
* 在标准初始化之后修改应用上下文的内部Bean定义注册表
* 所有常规Bean定义都已加载,但还没有Bean被实例化
* 这允许在下一个后处理阶段开始之前添加更多的Bean定义
*/
void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry)
throws BeansException;
}核心能力
graph LR
A[BeanDefinitionRegistryPostProcessor] --> B[注册新Bean定义]
A --> C[移除Bean定义]
A --> D[修改Bean定义]
A --> E[检查Bean定义]
style A fill:#e74c3c,stroke:#c0392b,color:#fff,rx:10,ry:10
style B fill:#3498db,stroke:#2980b9,color:#fff,rx:10,ry:10
style C fill:#9b59b6,stroke:#8e44ad,color:#fff,rx:10,ry:10
style D fill:#2ecc71,stroke:#27ae60,color:#fff,rx:10,ry:10
style E fill:#e67e22,stroke:#d35400,color:#fff,rx:10,ry:10使用场景
场景一:动态注册Bean定义
@Component
public class CustomBeanRegistrar implements BeanDefinitionRegistryPostProcessor {
@Override
public void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry)
throws BeansException {
// 动态创建一个Bean定义
GenericBeanDefinition beanDefinition = new GenericBeanDefinition();
beanDefinition.setBeanClass(DynamicService.class);
beanDefinition.setScope(BeanDefinition.SCOPE_SINGLETON);
beanDefinition.setLazyInit(false);
// 设置构造器参数
beanDefinition.getConstructorArgumentValues()
.addGenericArgumentValue("动态创建的服务");
// 注册到容器
registry.registerBeanDefinition("dynamicService", beanDefinition);
System.out.println("动态注册了Bean: dynamicService");
}
@Override
public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory)
throws BeansException {
// 这个方法来自BeanFactoryPostProcessor
}
}场景二:扫描自定义注解并注册Bean
/**
* 自定义注解
*/
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
public @interface RpcService {
String value() default "";
}
/**
* 扫描@RpcService注解并注册Bean
*/
@Component
public class RpcServiceRegistrar implements BeanDefinitionRegistryPostProcessor {
@Override
public void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry)
throws BeansException {
// 创建类路径扫描器
ClassPathScanningCandidateComponentProvider scanner =
new ClassPathScanningCandidateComponentProvider(false);
// 添加自定义注解过滤器
scanner.addIncludeFilter(new AnnotationTypeFilter(RpcService.class));
// 扫描指定包
Set<BeanDefinition> candidates = scanner.findCandidateComponents("com.example.rpc");
for (BeanDefinition candidate : candidates) {
// 获取Bean类名
String beanClassName = candidate.getBeanClassName();
String beanName = generateBeanName(beanClassName);
// 注册Bean定义
registry.registerBeanDefinition(beanName, candidate);
System.out.println("注册RPC服务: " + beanName);
}
}
private String generateBeanName(String className) {
String simpleName = className.substring(className.lastIndexOf('.') + 1);
return Character.toLowerCase(simpleName.charAt(0)) + simpleName.substring(1);
}
@Override
public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) {
// 可以在这里做额外处理
}
}Spring中的典型应用
graph TB
A[ConfigurationClassPostProcessor<br/>处理Configuration注解]
B[MapperScannerConfigurer<br/>MyBatis扫描Mapper接口]
C[ServiceAnnotationBeanPostProcessor<br/>Dubbo服务注册]
style A fill:#3498db,stroke:#2980b9,color:#fff,rx:10,ry:10
style B fill:#2ecc71,stroke:#27ae60,color:#fff,rx:10,ry:10
style C fill:#9b59b6,stroke:#8e44ad,color:#fff,rx:10,ry:10ConfigurationClassPostProcessor 是Spring中最重要的BeanDefinitionRegistryPostProcessor实现:
// Spring内部实现(简化版)
public class ConfigurationClassPostProcessor
implements BeanDefinitionRegistryPostProcessor {
@Override
public void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry) {
// 1. 找出所有@Configuration类
// 2. 解析@Bean方法,注册为Bean定义
// 3. 处理@ComponentScan,扫描并注册组件
// 4. 处理@Import,导入额外配置
// 5. 处理@ImportResource,导入XML配置
}
}BeanFactoryPostProcessor详解
接口定义
BeanFactoryPostProcessor在Bean定义加载完成后、Bean实例化之前执行,用于修改Bean定义的属性。
@FunctionalInterface
public interface BeanFactoryPostProcessor {
/**
* 在应用上下文的标准初始化之后修改其内部的Bean工厂
* 所有Bean定义都已加载,但还没有Bean被实例化
* 这允许覆盖或添加属性,甚至可以预先初始化Bean
*/
void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory)
throws BeansException;
}核心能力
graph LR
A[BeanFactoryPostProcessor] --> B[修改Bean属性值]
A --> C[修改Bean作用域]
A --> D[修改Bean依赖]
A --> E[添加属性值]
style A fill:#3498db,stroke:#2980b9,color:#fff,rx:10,ry:10
style B fill:#2ecc71,stroke:#27ae60,color:#fff,rx:10,ry:10
style C fill:#9b59b6,stroke:#8e44ad,color:#fff,rx:10,ry:10
style D fill:#e74c3c,stroke:#c0392b,color:#fff,rx:10,ry:10
style E fill:#e67e22,stroke:#d35400,color:#fff,rx:10,ry:10使用场景
场景一:修改Bean定义的属性
@Component
public class BeanPropertyModifier implements BeanFactoryPostProcessor {
@Override
public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory)
throws BeansException {
// 获取指定Bean的定义
BeanDefinition beanDefinition = beanFactory.getBeanDefinition("dataSource");
// 修改属性值
MutablePropertyValues propertyValues = beanDefinition.getPropertyValues();
propertyValues.addPropertyValue("maxPoolSize", 50);
propertyValues.addPropertyValue("minPoolSize", 10);
System.out.println("已修改dataSource的连接池配置");
}
}场景二:根据环境动态调整配置
@Component
public class EnvironmentAwareBeanModifier implements BeanFactoryPostProcessor {
@Autowired
private Environment environment;
@Override
public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory)
throws BeansException {
String activeProfile = environment.getActiveProfiles()[0];
// 根据环境修改Bean配置
if ("production".equals(activeProfile)) {
modifyForProduction(beanFactory);
} else if ("development".equals(activeProfile)) {
modifyForDevelopment(beanFactory);
}
}
private void modifyForProduction(ConfigurableListableBeanFactory beanFactory) {
// 生产环境:增加缓存配置
BeanDefinition cacheDef = beanFactory.getBeanDefinition("cacheManager");
cacheDef.getPropertyValues().addPropertyValue("maxSize", 10000);
}
private void modifyForDevelopment(ConfigurableListableBeanFactory beanFactory) {
// 开发环境:启用调试模式
BeanDefinition loggerDef = beanFactory.getBeanDefinition("loggerConfig");
loggerDef.getPropertyValues().addPropertyValue("level", "DEBUG");
}
}场景三:遍历所有Bean定义并处理
@Component
public class BeanDefinitionInspector implements BeanFactoryPostProcessor {
@Override
public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory)
throws BeansException {
String[] beanNames = beanFactory.getBeanDefinitionNames();
for (String beanName : beanNames) {
BeanDefinition beanDefinition = beanFactory.getBeanDefinition(beanName);
// 检查是否是单例
if (beanDefinition.isSingleton()) {
System.out.println("单例Bean: " + beanName);
}
// 检查是否懒加载
if (beanDefinition.isLazyInit()) {
System.out.println("懒加载Bean: " + beanName);
}
// 获取Bean类名
String className = beanDefinition.getBeanClassName();
System.out.println("Bean类型: " + className);
}
}
}Spring中的典型应用
PropertySourcesPlaceholderConfigurer - 处理配置文件占位符:
// 配置示例
@Configuration
public class AppConfig {
@Bean
public static PropertySourcesPlaceholderConfigurer propertyConfigurer() {
PropertySourcesPlaceholderConfigurer configurer =
new PropertySourcesPlaceholderConfigurer();
configurer.setLocation(new ClassPathResource("application.properties"));
return configurer;
}
}
// application.properties
// database.url=jdbc:mysql://localhost:3306/mydb
// database.username=root
// 使用占位符
@Component
public class DatabaseConfig {
@Value("${database.url}")
private String url;
@Value("${database.username}")
private String username;
}graph TB
A[PropertySourcesPlaceholderConfigurer] --> B[加载配置文件]
B --> C[解析占位符$...]
C --> D[替换Bean定义中的属性值]
D --> E[Bean实例化时使用替换后的值]
style A fill:#3498db,stroke:#2980b9,color:#fff,rx:10,ry:10
style B fill:#2ecc71,stroke:#27ae60,color:#fff,rx:10,ry:10
style C fill:#9b59b6,stroke:#8e44ad,color:#fff,rx:10,ry:10
style D fill:#e74c3c,stroke:#c0392b,color:#fff,rx:10,ry:10
style E fill:#e67e22,stroke:#d35400,color:#fff,rx:10,ry:10BeanPostProcessor详解
接口定义
BeanPostProcessor是最常用的后置处理器,在Bean实例化之后、初始化前后执行。
public interface BeanPostProcessor {
/**
* 在Bean初始化回调(如InitializingBean的afterPropertiesSet或自定义init方法)
* 之前执行
*/
@Nullable
default Object postProcessBeforeInitialization(Object bean, String beanName)
throws BeansException {
return bean;
}
/**
* 在Bean初始化回调之后执行
* 此时可以返回包装后的Bean(如代理对象)
*/
@Nullable
default Object postProcessAfterInitialization(Object bean, String beanName)
throws BeansException {
return bean;
}
}执行时机详解
graph TB
A["Bean实例化<br/>new Object"] --> B["属性注入<br/>Autowired"]
B --> C["postProcessBeforeInitialization<br/>初始化前处理"]
C --> D["PostConstruct<br/>初始化方法"]
D --> E["InitializingBean.afterPropertiesSet<br/>初始化回调"]
E --> F["自定义init-method<br/>初始化方法"]
F --> G["postProcessAfterInitialization<br/>初始化后处理"]
G --> H["Bean可用<br/>返回给容器"]
style A fill:#3498db,stroke:#2980b9,color:#fff,rx:10,ry:10
style C fill:#e74c3c,stroke:#c0392b,color:#fff,rx:10,ry:10
style D fill:#2ecc71,stroke:#27ae60,color:#fff,rx:10,ry:10
style G fill:#e74c3c,stroke:#c0392b,color:#fff,rx:10,ry:10
style H fill:#9b59b6,stroke:#8e44ad,color:#fff,rx:10,ry:10使用场景
场景一:自定义注解处理
/**
* 自定义日志注解
*/
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
public @interface EnableLogging {
String prefix() default "";
}
/**
* 处理@EnableLogging注解的后置处理器
*/
@Component
public class LoggingBeanPostProcessor implements BeanPostProcessor {
@Override
public Object postProcessBeforeInitialization(Object bean, String beanName)
throws BeansException {
EnableLogging annotation = bean.getClass().getAnnotation(EnableLogging.class);
if (annotation != null) {
System.out.println("[" + annotation.prefix() + "] 初始化前: " + beanName);
}
return bean;
}
@Override
public Object postProcessAfterInitialization(Object bean, String beanName)
throws BeansException {
EnableLogging annotation = bean.getClass().getAnnotation(EnableLogging.class);
if (annotation != null) {
System.out.println("[" + annotation.prefix() + "] 初始化后: " + beanName);
}
return bean;
}
}
// 使用
@Service
@EnableLogging(prefix = "UserService")
public class UserService {
// 服务实现
}场景二:创建代理对象(AOP核心原理)
/**
* 性能监控注解
*/
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
public @interface PerformanceMonitor {
}
/**
* 创建性能监控代理的后置处理器
*/
@Component
public class PerformanceMonitorPostProcessor implements BeanPostProcessor {
@Override
public Object postProcessAfterInitialization(Object bean, String beanName)
throws BeansException {
// 检查是否有@PerformanceMonitor注解
if (bean.getClass().isAnnotationPresent(PerformanceMonitor.class)) {
// 创建JDK动态代理
return Proxy.newProxyInstance(
bean.getClass().getClassLoader(),
bean.getClass().getInterfaces(),
(proxy, method, args) -> {
long start = System.currentTimeMillis();
try {
return method.invoke(bean, args);
} finally {
long cost = System.currentTimeMillis() - start;
System.out.println(method.getName() + " 执行耗时: " + cost + "ms");
}
}
);
}
return bean;
}
}
// 使用
public interface OrderService {
void createOrder(Order order);
}
@Service
@PerformanceMonitor
public class OrderServiceImpl implements OrderService {
@Override
public void createOrder(Order order) {
// 创建订单逻辑
Thread.sleep(100); // 模拟耗时
}
}场景三:属性校验
/**
* 必需属性注解
*/
@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
public @interface Required {
String message() default "属性不能为空";
}
/**
* 属性校验后置处理器
*/
@Component
public class RequiredFieldPostProcessor implements BeanPostProcessor {
@Override
public Object postProcessAfterInitialization(Object bean, String beanName)
throws BeansException {
Class<?> clazz = bean.getClass();
for (Field field : clazz.getDeclaredFields()) {
Required required = field.getAnnotation(Required.class);
if (required != null) {
field.setAccessible(true);
try {
Object value = field.get(bean);
if (value == null) {
throw new BeanCreationException(beanName,
field.getName() + ": " + required.message());
}
} catch (IllegalAccessException e) {
throw new BeanCreationException(beanName, "无法访问字段", e);
}
}
}
return bean;
}
}
// 使用
@Service
public class ConfigService {
@Required(message = "数据库URL必须配置")
@Value("${database.url}")
private String databaseUrl;
@Required
@Autowired
private DataSource dataSource;
}Spring中的典型应用
graph TB
A["AutowiredAnnotationBeanPostProcessor<br/>处理Autowired注入"]
B["CommonAnnotationBeanPostProcessor<br/>处理Resource、PostConstruct"]
C["AbstractAutoProxyCreator<br/>AOP代理创建"]
D["ApplicationContextAwareProcessor<br/>处理Aware接口回调"]
style A fill:#3498db,stroke:#2980b9,color:#fff,rx:10,ry:10
style B fill:#2ecc71,stroke:#27ae60,color:#fff,rx:10,ry:10
style C fill:#e74c3c,stroke:#c0392b,color:#fff,rx:10,ry:10
style D fill:#9b59b6,stroke:#8e44ad,color:#fff,rx:10,ry:10InstantiationAwareBeanPostProcessor
接口定义
InstantiationAwareBeanPostProcessor继承自BeanPostProcessor,提供了更细粒度的控制,可以在Bean实例化之前介入。
public interface InstantiationAwareBeanPostProcessor extends BeanPostProcessor {
/**
* 在Bean实例化之前调用
* 如果返回非null,将使用返回的对象作为Bean,跳过正常的实例化过程
*/
@Nullable
default Object postProcessBeforeInstantiation(Class<?> beanClass, String beanName)
throws BeansException {
return null;
}
/**
* 在Bean实例化之后、属性注入之前调用
* 返回false将阻止属性注入
*/
default boolean postProcessAfterInstantiation(Object bean, String beanName)
throws BeansException {
return true;
}
/**
* 在属性注入之前处理属性值
*/
@Nullable
default PropertyValues postProcessProperties(PropertyValues pvs, Object bean,
String beanName) throws BeansException {
return null;
}
}完整生命周期
graph TB
A[postProcessBeforeInstantiation<br/>实例化前] --> B{返回非null?}
B -->|是| C[跳过实例化,使用返回对象]
B -->|否| D[正常实例化Bean]
D --> E[postProcessAfterInstantiation<br/>实例化后]
E --> F{返回true?}
F -->|是| G[postProcessProperties<br/>处理属性]
F -->|否| H[跳过属性注入]
G --> I[属性注入]
I --> J[postProcessBeforeInitialization<br/>初始化前]
J --> K[初始化方法]
K --> L[postProcessAfterInitialization<br/>初始化后]
style A fill:#e74c3c,stroke:#c0392b,color:#fff,rx:10,ry:10
style E fill:#3498db,stroke:#2980b9,color:#fff,rx:10,ry:10
style G fill:#9b59b6,stroke:#8e44ad,color:#fff,rx:10,ry:10
style J fill:#2ecc71,stroke:#27ae60,color:#fff,rx:10,ry:10
style L fill:#e67e22,stroke:#d35400,color:#fff,rx:10,ry:10使用场景
场景:自定义实例化策略
@Component
public class CustomInstantiationProcessor
implements InstantiationAwareBeanPostProcessor {
@Override
public Object postProcessBeforeInstantiation(Class<?> beanClass, String beanName)
throws BeansException {
// 对于特定的Bean,使用自定义实例化
if (beanClass.isAnnotationPresent(CustomCreate.class)) {
try {
// 使用工厂方法创建
Method factoryMethod = beanClass.getMethod("create");
return factoryMethod.invoke(null);
} catch (Exception e) {
throw new BeanCreationException(beanName, "自定义创建失败", e);
}
}
return null; // 返回null使用正常实例化
}
@Override
public boolean postProcessAfterInstantiation(Object bean, String beanName)
throws BeansException {
// 检查是否需要跳过属性注入
if (bean.getClass().isAnnotationPresent(NoAutowire.class)) {
return false; // 跳过属性注入
}
return true;
}
}SmartInstantiationAwareBeanPostProcessor
接口定义
SmartInstantiationAwareBeanPostProcessor是InstantiationAwareBeanPostProcessor的扩展,提供了更智能的处理能力。
public interface SmartInstantiationAwareBeanPostProcessor
extends InstantiationAwareBeanPostProcessor {
/**
* 预测Bean的最终类型
*/
@Nullable
default Class<?> predictBeanType(Class<?> beanClass, String beanName)
throws BeansException {
return null;
}
/**
* 确定候选的构造器
*/
@Nullable
default Constructor<?>[] determineCandidateConstructors(Class<?> beanClass,
String beanName) throws BeansException {
return null;
}
/**
* 获取早期Bean引用(解决循环依赖)
*/
default Object getEarlyBeanReference(Object bean, String beanName)
throws BeansException {
return bean;
}
}解决循环依赖的关键
graph TB
subgraph 循环依赖场景
A[创建Bean A] --> B[发现依赖Bean B]
B --> C[创建Bean B]
C --> D[发现依赖Bean A]
D --> E[获取A的早期引用]
E --> F[getEarlyBeanReference]
F --> G[返回A的代理或原始对象]
G --> H[B创建完成]
H --> I[A创建完成]
end
style A fill:#3498db,stroke:#2980b9,color:#fff,rx:10,ry:10
style F fill:#e74c3c,stroke:#c0392b,color:#fff,rx:10,ry:10
style G fill:#2ecc71,stroke:#27ae60,color:#fff,rx:10,ry:10
style I fill:#9b59b6,stroke:#8e44ad,color:#fff,rx:10,ry:10DestructionAwareBeanPostProcessor
接口定义
DestructionAwareBeanPostProcessor用于在Bean销毁前执行清理操作。
public interface DestructionAwareBeanPostProcessor extends BeanPostProcessor {
/**
* 在Bean销毁之前调用
*/
void postProcessBeforeDestruction(Object bean, String beanName)
throws BeansException;
/**
* 判断是否需要销毁回调
*/
default boolean requiresDestruction(Object bean) {
return true;
}
}使用场景
@Component
public class CleanupPostProcessor implements DestructionAwareBeanPostProcessor {
@Override
public void postProcessBeforeDestruction(Object bean, String beanName)
throws BeansException {
// 检查是否实现了Closeable接口
if (bean instanceof Closeable) {
try {
((Closeable) bean).close();
System.out.println("已关闭资源: " + beanName);
} catch (IOException e) {
System.err.println("关闭资源失败: " + beanName);
}
}
// 检查自定义注解
if (bean.getClass().isAnnotationPresent(Cleanup.class)) {
invokeCleanupMethods(bean, beanName);
}
}
private void invokeCleanupMethods(Object bean, String beanName) {
for (Method method : bean.getClass().getDeclaredMethods()) {
if (method.isAnnotationPresent(CleanupMethod.class)) {
try {
method.setAccessible(true);
method.invoke(bean);
} catch (Exception e) {
System.err.println("清理方法执行失败: " + method.getName());
}
}
}
}
@Override
public boolean requiresDestruction(Object bean) {
return bean instanceof Closeable
|| bean.getClass().isAnnotationPresent(Cleanup.class);
}
}MergedBeanDefinitionPostProcessor
接口定义
MergedBeanDefinitionPostProcessor在Bean定义合并后、实例化之前执行,用于收集元数据。
public interface MergedBeanDefinitionPostProcessor extends BeanPostProcessor {
/**
* 在Bean实例化之前,对合并后的Bean定义进行后处理
* 通常用于收集注解元数据
*/
void postProcessMergedBeanDefinition(RootBeanDefinition beanDefinition,
Class<?> beanType, String beanName);
/**
* 重置Bean定义(用于prototype作用域)
*/
default void resetBeanDefinition(String beanName) {
}
}Spring中的应用
// AutowiredAnnotationBeanPostProcessor的简化实现
public class AutowiredAnnotationBeanPostProcessor
implements MergedBeanDefinitionPostProcessor, BeanPostProcessor {
// 缓存注入元数据
private final Map<String, InjectionMetadata> injectionMetadataCache =
new ConcurrentHashMap<>();
@Override
public void postProcessMergedBeanDefinition(RootBeanDefinition beanDefinition,
Class<?> beanType, String beanName) {
// 在实例化之前,先收集@Autowired注解信息
InjectionMetadata metadata = findAutowiringMetadata(beanName, beanType);
metadata.checkConfigMembers(beanDefinition);
// 缓存起来,后续属性注入时使用
injectionMetadataCache.put(beanName, metadata);
}
@Override
public Object postProcessBeforeInitialization(Object bean, String beanName) {
// 执行属性注入
InjectionMetadata metadata = injectionMetadataCache.get(beanName);
if (metadata != null) {
metadata.inject(bean, beanName, null);
}
return bean;
}
}后置处理器执行顺序
完整执行流程
graph TB
A["加载Bean定义"] --> B["BeanDefinitionRegistryPostProcessor"]
B --> C["BeanFactoryPostProcessor"]
C --> D["MergedBeanDefinitionPostProcessor"]
D --> E["postProcessBeforeInstantiation"]
E --> F["Bean实例化"]
F --> G["postProcessAfterInstantiation"]
G --> H["postProcessProperties"]
H --> I["属性注入"]
I --> J["postProcessBeforeInitialization"]
J --> K["初始化方法"]
K --> L["postProcessAfterInitialization"]
L --> M["Bean使用"]
M --> N["postProcessBeforeDestruction"]
N --> O["销毁方法"]
style B fill:#e74c3c,stroke:#c0392b,color:#fff,rx:10,ry:10
style C fill:#3498db,stroke:#2980b9,color:#fff,rx:10,ry:10
style J fill:#2ecc71,stroke:#27ae60,color:#fff,rx:10,ry:10
style L fill:#9b59b6,stroke:#8e44ad,color:#fff,rx:10,ry:10
style N fill:#e67e22,stroke:#d35400,color:#fff,rx:10,ry:10使用@Order控制顺序
@Component
@Order(1) // 优先级最高
public class FirstPostProcessor implements BeanPostProcessor {
@Override
public Object postProcessBeforeInitialization(Object bean, String beanName) {
System.out.println("第一个处理: " + beanName);
return bean;
}
}
@Component
@Order(2)
public class SecondPostProcessor implements BeanPostProcessor {
@Override
public Object postProcessBeforeInitialization(Object bean, String beanName) {
System.out.println("第二个处理: " + beanName);
return bean;
}
}实战综合案例
自定义依赖注入框架
/**
* 自定义注入注解
*/
@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
public @interface Inject {
String value() default "";
}
/**
* 自定义注入后置处理器
*/
@Component
public class CustomInjectionPostProcessor
implements MergedBeanDefinitionPostProcessor, BeanPostProcessor {
private final Map<String, List<Field>> injectionFieldsCache = new ConcurrentHashMap<>();
@Autowired
private ApplicationContext applicationContext;
@Override
public void postProcessMergedBeanDefinition(RootBeanDefinition beanDefinition,
Class<?> beanType, String beanName) {
// 收集@Inject注解的字段
List<Field> fields = new ArrayList<>();
ReflectionUtils.doWithFields(beanType, field -> {
if (field.isAnnotationPresent(Inject.class)) {
fields.add(field);
}
});
if (!fields.isEmpty()) {
injectionFieldsCache.put(beanName, fields);
}
}
@Override
public Object postProcessBeforeInitialization(Object bean, String beanName)
throws BeansException {
List<Field> fields = injectionFieldsCache.get(beanName);
if (fields != null) {
for (Field field : fields) {
Inject inject = field.getAnnotation(Inject.class);
String targetBeanName = inject.value();
// 如果没有指定名称,使用字段类型查找
Object dependency;
if (targetBeanName.isEmpty()) {
dependency = applicationContext.getBean(field.getType());
} else {
dependency = applicationContext.getBean(targetBeanName);
}
field.setAccessible(true);
try {
field.set(bean, dependency);
} catch (IllegalAccessException e) {
throw new BeanCreationException(beanName, "注入失败", e);
}
}
}
return bean;
}
}接口代理自动生成
/**
* RPC接口标记注解
*/
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
public @interface RpcClient {
String serviceUrl();
}
/**
* RPC代理工厂Bean
*/
public class RpcClientFactoryBean<T> implements FactoryBean<T> {
private Class<T> interfaceClass;
private String serviceUrl;
@Override
public T getObject() {
return (T) Proxy.newProxyInstance(
interfaceClass.getClassLoader(),
new Class[]{interfaceClass},
(proxy, method, args) -> {
// 模拟RPC调用
System.out.println("调用远程服务: " + serviceUrl);
System.out.println("方法: " + method.getName());
return null;
}
);
}
@Override
public Class<?> getObjectType() {
return interfaceClass;
}
// setters...
}
/**
* 扫描并注册RPC客户端
*/
@Component
public class RpcClientRegistrar implements BeanDefinitionRegistryPostProcessor {
@Override
public void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry) {
ClassPathScanningCandidateComponentProvider scanner =
new ClassPathScanningCandidateComponentProvider(false);
scanner.addIncludeFilter(new AnnotationTypeFilter(RpcClient.class));
for (BeanDefinition candidate : scanner.findCandidateComponents("com.example")) {
try {
Class<?> interfaceClass = Class.forName(candidate.getBeanClassName());
RpcClient annotation = interfaceClass.getAnnotation(RpcClient.class);
// 创建FactoryBean定义
GenericBeanDefinition beanDefinition = new GenericBeanDefinition();
beanDefinition.setBeanClass(RpcClientFactoryBean.class);
beanDefinition.getPropertyValues()
.addPropertyValue("interfaceClass", interfaceClass);
beanDefinition.getPropertyValues()
.addPropertyValue("serviceUrl", annotation.serviceUrl());
String beanName = Character.toLowerCase(interfaceClass.getSimpleName().charAt(0))
+ interfaceClass.getSimpleName().substring(1);
registry.registerBeanDefinition(beanName, beanDefinition);
} catch (ClassNotFoundException e) {
throw new RuntimeException(e);
}
}
}
@Override
public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) {
}
}
// 使用
@RpcClient(serviceUrl = "http://user-service/api")
public interface UserServiceClient {
User getUser(Long id);
}
@Service
public class OrderService {
@Autowired
private UserServiceClient userServiceClient; // 自动注入代理对象
public void createOrder(Long userId) {
User user = userServiceClient.getUser(userId);
// ...
}
}最佳实践
选择合适的后置处理器
graph TB
A{需要做什么?} --> B{动态注册Bean?}
B -->|是| C[BeanDefinitionRegistryPostProcessor]
B -->|否| D{修改Bean定义属性?}
D -->|是| E[BeanFactoryPostProcessor]
D -->|否| F{增强Bean实例?}
F -->|是| G[BeanPostProcessor]
F -->|否| H{控制实例化过程?}
H -->|是| I[InstantiationAwareBeanPostProcessor]
H -->|否| J{处理销毁逻辑?}
J -->|是| K[DestructionAwareBeanPostProcessor]
style C fill:#e74c3c,stroke:#c0392b,color:#fff,rx:10,ry:10
style E fill:#3498db,stroke:#2980b9,color:#fff,rx:10,ry:10
style G fill:#2ecc71,stroke:#27ae60,color:#fff,rx:10,ry:10
style I fill:#9b59b6,stroke:#8e44ad,color:#fff,rx:10,ry:10
style K fill:#e67e22,stroke:#d35400,color:#fff,rx:10,ry:10注意事项
| 注意点 | 说明 |
|---|---|
| 避免循环依赖 | 后置处理器本身不应该依赖需要处理的Bean |
| 返回原对象 | 如果不需要修改,务必返回原对象而非null |
| 异常处理 | 后置处理器抛出异常会导致容器启动失败 |
| 性能考虑 | 后置处理器对每个Bean都会执行,避免耗时操作 |
| 顺序控制 | 使用@Order或实现Ordered接口控制执行顺序 |
面试高频问题
BeanFactoryPostProcessor和BeanPostProcessor的区别?
| 对比项 | BeanFactoryPostProcessor | BeanPostProcessor |
|---|---|---|
| 操作对象 | BeanDefinition(Bean定义) | Bean实例 |
| 执行时机 | Bean实例化之前 | Bean实例化之后 |
| 执行次数 | 只执行一次 | 每个Bean实例化都执行 |
| 典型用途 | 修改配置、注册Bean定义 | 包装/增强Bean实例 |
Spring AOP是如何实现的?
Spring AOP通过AbstractAutoProxyCreator(实现了BeanPostProcessor)在postProcessAfterInitialization阶段为目标Bean创建代理对象:
public Object postProcessAfterInitialization(Object bean, String beanName) {
if (bean != null) {
Object cacheKey = getCacheKey(bean.getClass(), beanName);
// 判断是否需要代理
if (isEligibleForProxying(bean, beanName)) {
// 创建代理对象
return wrapIfNecessary(bean, beanName, cacheKey);
}
}
return bean;
}@Autowired是如何实现的?
AutowiredAnnotationBeanPostProcessor负责处理@Autowired注解:
postProcessMergedBeanDefinition:收集注入元数据postProcessProperties:执行实际的依赖注入
更新: 2025-12-06 13:12:31
原文: https://www.yuque.com/u22210564/zoxfmt/vvmfyobkn72z4ysm