spring 之 BeanPostProcessor

本文详细解析了Spring框架中BeanPostProcessor接口的功能及其工作原理。该接口通过提供两个方法(postProcessBeforeInitialization和postProcessAfterInitialization)来允许开发者在每个Bean实例化前后执行自定义操作。介绍了BeanPostProcessor在Spring生命周期中的作用,并展示了AbstractAutowireCapableBeanFactory类中相关方法的具体实现。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

粗略一看, 它有这么多实现:

可见, 它是多么基础 而重要的一个 接口啊! 它提供了两个方法:

public interface BeanPostProcessor {
    Object postProcessBeforeInitialization(Object var1, String var2) throws BeansException;

    Object postProcessAfterInitialization(Object var1, String var2) throws BeansException;
}

两个方法的名字 都是  postProcessXxxInitialization 的格式, 不是 Before 就是 After,  都是围绕 process Initialization  这个过程来做文章的。  当然, 我有一点不明白的是, 为什么  这里有个post, post作为前缀有 在... 之后的意思(http://skill.qsbdc.com/cigencizhui/328.html),但是在这里,和Before一起使用, 有些难以理解。

 

如果我们自定义的class 实现了 这个接口,  那么它会在每一个 bean 的实例化前后 各被调用一次。 参见AbstractAutowireCapableBeanFactory 源码:

    public Object applyBeanPostProcessorsBeforeInitialization(Object existingBean, String beanName) throws BeansException {
        Object result = existingBean;
        Iterator var4 = this.getBeanPostProcessors().iterator();

        do {
            if(!var4.hasNext()) {
                return result;
            }

            BeanPostProcessor beanProcessor = (BeanPostProcessor)var4.next();
            result = beanProcessor.postProcessBeforeInitialization(result, beanName);  // 前处理
        } while(result != null);

        return result;
    }

    public Object applyBeanPostProcessorsAfterInitialization(Object existingBean, String beanName) throws BeansException {
        Object result = existingBean;
        Iterator var4 = this.getBeanPostProcessors().iterator();

        do {
            if(!var4.hasNext()) {
                return result;
            }

            BeanPostProcessor beanProcessor = (BeanPostProcessor)var4.next();
            result = beanProcessor.postProcessAfterInitialization(result, beanName);// 后处理
        } while(result != null);

        return result;
    }

这两个方法都是在初始化bean 的时候被调用的:

    protected Object initializeBean(final String beanName, final Object bean, RootBeanDefinition mbd) {
        if(System.getSecurityManager() != null) {
            AccessController.doPrivileged(new PrivilegedAction() {
                public Object run() {
                    AbstractAutowireCapableBeanFactory.this.invokeAwareMethods(beanName, bean);
                    return null;
                }
            }, this.getAccessControlContext());
        } else {
            this.invokeAwareMethods(beanName, bean);
        }

        Object wrappedBean = bean;
        if(mbd == null || !mbd.isSynthetic()) {
            wrappedBean = this.applyBeanPostProcessorsBeforeInitialization(bean, beanName); // 前处理
        }

        try {
            this.invokeInitMethods(beanName, wrappedBean, mbd);
        } catch (Throwable var6) {
            throw new BeanCreationException(mbd != null?mbd.getResourceDescription():null, beanName, "Invocation of init method failed", var6);
        }

        if(mbd == null || !mbd.isSynthetic()) {
            wrappedBean = this.applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);//  后处理
        }

        return wrappedBean;
    }

 

<think>我们正在讨论SpringBeanPostProcessor的执行时机。根据提供的引用材料,特别是引用[4]中的描述,BeanPostProcessor在Bean初始化过程中有两个关键的执行点:初始化之前和初始化之后。具体来说: 1.在Bean的初始化方法(如@PostConstruct标注的方法、InitializingBean的afterPropertiesSet方法或自定义的init方法)之前,会执行BeanPostProcessor的postProcessBeforeInitialization方法。 2.在Bean的初始化方法之后,会执行BeanPostProcessor的postProcessAfterInitialization方法。引用[4]中的代码片段展示了applyBeanPostProcessorsBeforeInitialization方法的实现,该方法遍历所有BeanPostProcessor并调用它们的postProcessBeforeInitialization方法。 因此,我们可以总结如下:- **执行时机1(初始化之前)**:在Bean属性设置完成(即依赖注入完成)之后,但在任何初始化回调(如@PostConstruct)之前,Spring会调用所有BeanPostProcessor的postProcessBeforeInitialization方法。- **执行时机2(初始化之后)**:在Bean的初始化回调(如@PostConstruct、afterPropertiesSet或自定义init方法)执行完毕之后,Spring会调用所有BeanPostProcessor的postProcessAfterInitialization方法。 这两个时机允许开发者对Bean进行额外的处理或包装(例如生成代理对象),从而扩展Spring容器的功能。 为了更清晰地理解,我们可以参考以下简化的Bean生命周期步骤:1.实例化Bean(通过构造函数或工厂方法) 2.属性赋值(依赖注入)3.**BeanPostProcessor的postProcessBeforeInitialization方法**4.初始化方法(@PostConstruct,InitializingBean的afterPropertiesSet,自定义init方法) 5. **BeanPostProcessor的postProcessAfterInitialization方法** 6. Bean就绪,可以使用7.容器关闭时,执行销毁方法(@PreDestroy, DisposableBean的destroy方法,自定义destroy方法) 注意:对于prototype作用域的Bean,Spring容器不会管理其完整的生命周期,但BeanPostProcessor仍然会在初始化阶段被调用(即步骤3和5)。希望这个解释能帮助你理解BeanPostProcessor的执行时机。§§相关问题§§1.如何自定义一个BeanPostProcessor? 2. BeanPostProcessor和BeanFactoryPostProcessor有什么区别? 3.在postProcessBeforeInitialization和postProcessAfterInitialization中分别适合做什么操作?</think>### Spring BeanPostProcessor 的执行时机 在 Spring 的生命周期中,`BeanPostProcessor` 在两个关键节点介入: 1. **初始化前拦截**(`postProcessBeforeInitialization`) **执行时机**:在 Bean 的依赖注入完成后,但在任何初始化回调(如 `@PostConstruct`、`InitializingBean` 的 `afterPropertiesSet` 或自定义 `init-method`)之前触发。 **作用**:可对 Bean 实例进行预处理(如修改属性值、生成代理对象)。 **源码流程**: ```java // AbstractAutowireCapableBeanFactory protected Object applyBeanPostProcessorsBeforeInitialization(Object bean, String beanName) { for (BeanPostProcessor processor : getBeanPostProcessors()) { bean = processor.postProcessBeforeInitialization(bean, beanName); } return bean; } ``` [^4] 2. **初始化后拦截**(`postProcessAfterInitialization`) **执行时机**:在所有初始化回调完成后,Bean 已完全初始化但尚未投入使用前触发。 **作用**:可对 Bean 进行最终包装(如 AOP 代理增强)。 **典型场景**:Spring AOP 在此阶段创建代理对象。 --- ### 完整生命周期中的定位 ```mermaid graph TD A[实例化Bean] --> B[属性注入] B --> C[执行Aware接口方法] C --> D[BeanPostProcessor.postProcessBeforeInitialization] D --> E[初始化回调:@PostConstruct/afterPropertiesSet] E --> F[BeanPostProcessor.postProcessAfterInitialization] F --> G[Bean就绪] G --> H[容器关闭时执行销毁回调] ``` > **关键规则**: > - 对 `singleton` Bean 全程生效 > - 对 `prototype` Bean 仅生效到初始化完成阶段(销毁不由容器管理)[^2] > - 每个 `BeanPostProcessor` 会作用于**所有** Bean 的创建过程 --- ### 实际应用示例 ```java @Component public class CustomProcessor implements BeanPostProcessor { @Override public Object postProcessBeforeInitialization(Object bean, String name) { System.out.println("Before init: " + name); return bean; // 可返回修改后的Bean } @Override public Object postProcessAfterInitialization(Object bean, String name) { System.out.println("After init: " + name); return bean; } } ``` 此处理器会在每个 Bean 初始化前后打印日志,常用于调试或扩展功能[^1]。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值