Skip to content

Spring后置处理器详解

后置处理器概述

在Spring框架中,后置处理器(Post Processor)是一种扩展机制,允许开发者在Bean创建和容器初始化的不同阶段介入,对Bean定义或Bean实例进行自定义处理。

Spring提供了三个核心后置处理器接口,它们在容器生命周期的不同阶段发挥作用:

mermaid
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

三者的核心区别

处理器类型作用阶段操作对象典型用途
BeanDefinitionRegistryPostProcessorBean定义加载后,实例化前BeanDefinition注册表动态注册新的Bean定义
BeanFactoryPostProcessorBean定义加载后,实例化前BeanDefinition属性修改Bean定义的属性值
BeanPostProcessorBean实例化后,初始化前后Bean实例包装/增强Bean实例

执行时序

mermaid
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中最早执行的后置处理器。

java
public interface BeanDefinitionRegistryPostProcessor 
        extends BeanFactoryPostProcessor {
    
    /**
     * 在标准初始化之后修改应用上下文的内部Bean定义注册表
     * 所有常规Bean定义都已加载,但还没有Bean被实例化
     * 这允许在下一个后处理阶段开始之前添加更多的Bean定义
     */
    void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry) 
            throws BeansException;
}

核心能力

mermaid
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定义

java
@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

java
/**
 * 自定义注解
 */
@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中的典型应用

mermaid
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:10

ConfigurationClassPostProcessor 是Spring中最重要的BeanDefinitionRegistryPostProcessor实现:

java
// 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定义的属性

java
@FunctionalInterface
public interface BeanFactoryPostProcessor {
    
    /**
     * 在应用上下文的标准初始化之后修改其内部的Bean工厂
     * 所有Bean定义都已加载,但还没有Bean被实例化
     * 这允许覆盖或添加属性,甚至可以预先初始化Bean
     */
    void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) 
            throws BeansException;
}

核心能力

mermaid
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定义的属性

java
@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的连接池配置");
    }
}

场景二:根据环境动态调整配置

java
@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定义并处理

java
@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 - 处理配置文件占位符:

java
// 配置示例
@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;
}
mermaid
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:10

BeanPostProcessor详解

接口定义

BeanPostProcessor是最常用的后置处理器,在Bean实例化之后、初始化前后执行。

java
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;
    }
}

执行时机详解

mermaid
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

使用场景

场景一:自定义注解处理

java
/**
 * 自定义日志注解
 */
@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核心原理)

java
/**
 * 性能监控注解
 */
@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); // 模拟耗时
    }
}

场景三:属性校验

java
/**
 * 必需属性注解
 */
@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中的典型应用

mermaid
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:10

InstantiationAwareBeanPostProcessor

接口定义

InstantiationAwareBeanPostProcessor继承自BeanPostProcessor,提供了更细粒度的控制,可以在Bean实例化之前介入。

java
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;
    }
}

完整生命周期

mermaid
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

使用场景

场景:自定义实例化策略

java
@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

接口定义

SmartInstantiationAwareBeanPostProcessorInstantiationAwareBeanPostProcessor的扩展,提供了更智能的处理能力。

java
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;
    }
}

解决循环依赖的关键

mermaid
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:10

DestructionAwareBeanPostProcessor

接口定义

DestructionAwareBeanPostProcessor用于在Bean销毁前执行清理操作。

java
public interface DestructionAwareBeanPostProcessor extends BeanPostProcessor {
    
    /**
     * 在Bean销毁之前调用
     */
    void postProcessBeforeDestruction(Object bean, String beanName) 
            throws BeansException;
    
    /**
     * 判断是否需要销毁回调
     */
    default boolean requiresDestruction(Object bean) {
        return true;
    }
}

使用场景

java
@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定义合并后、实例化之前执行,用于收集元数据。

java
public interface MergedBeanDefinitionPostProcessor extends BeanPostProcessor {
    
    /**
     * 在Bean实例化之前,对合并后的Bean定义进行后处理
     * 通常用于收集注解元数据
     */
    void postProcessMergedBeanDefinition(RootBeanDefinition beanDefinition, 
            Class<?> beanType, String beanName);
    
    /**
     * 重置Bean定义(用于prototype作用域)
     */
    default void resetBeanDefinition(String beanName) {
    }
}

Spring中的应用

java
// 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;
    }
}

后置处理器执行顺序

完整执行流程

mermaid
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控制顺序

java
@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;
    }
}

实战综合案例

自定义依赖注入框架

java
/**
 * 自定义注入注解
 */
@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;
    }
}

接口代理自动生成

java
/**
 * 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);
        // ...
    }
}

最佳实践

选择合适的后置处理器

mermaid
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的区别?

对比项BeanFactoryPostProcessorBeanPostProcessor
操作对象BeanDefinition(Bean定义)Bean实例
执行时机Bean实例化之前Bean实例化之后
执行次数只执行一次每个Bean实例化都执行
典型用途修改配置、注册Bean定义包装/增强Bean实例

Spring AOP是如何实现的?

Spring AOP通过AbstractAutoProxyCreator(实现了BeanPostProcessor)在postProcessAfterInitialization阶段为目标Bean创建代理对象:

java
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注解:

  1. postProcessMergedBeanDefinition:收集注入元数据
  2. postProcessProperties:执行实际的依赖注入

更新: 2025-12-06 13:12:31
原文: https://www.yuque.com/u22210564/zoxfmt/vvmfyobkn72z4ysm

Java 后端面试知识库