总结Spring中工厂后处理器

本文介绍了Spring中的两种工厂后处理器:BeanFactoryPostProcessor和BeanDefinitionRegistryPostProcessor,详细阐述了它们的作用、执行顺序及应用场景。

工厂处理器是一种特殊的Bean,这种Bean并不对外提供服务,它甚至可以无需id属性,它主要负责对容器本身进行某些特殊的处理。Spring中有两类工厂后处理器,一个是BeanFactoryPostProcessor,它是所有工厂后处理器的顶层接口;另一个是BeanDefinitionRegistryPostProcessor,它继承自BeanFactoryPostProcessor,设计它的目的是使用它向Bean注册表(一个BeanDefinitionRegistry 对象)中注册bean的配置信息——一个BeanDefinition对象。

BeanFactoryPostProcessor的定义

Spring工厂后处理器的顶层接口org.springframework.beans.factory.config.BeanFactoryPostProcessor的定义如下。

public interface BeanFactoryPostProcessor {

    /**
     * Modify the application context's internal bean factory after its standard
     * initialization. All bean definitions will have been loaded, but no beans
     * will have been instantiated yet. This allows for overriding or adding
     * properties even to eager-initializing beans.
     * @param beanFactory the bean factory used by the application context
     * @throws org.springframework.beans.BeansException in case of errors
     */
    void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException;

}

postProcessBeanFactory方法在BeanFactory对象实例化完成后,当所有的bean的BeanDefinition对象加载完成时(即,所有bean的配置信息都已经注册到bean注册表中)被调用。它允许覆盖或者设置bean的属性值,甚至是立即实例化bean,比如实例化bean后处理器对象。

BeanDefinitionRegistryPostProcessor的定义

Spring还定义了一个工厂后处理器接口,那就是org.springframework.beans.factory.support.BeanDefinitionRegistryPostProcessor,该接口继承了BeanFactoryPostProcessor。下面是它的源码定义。

public interface BeanDefinitionRegistryPostProcessor extends BeanFactoryPostProcessor {

    /**
     * Modify the application context's internal bean definition registry after its
     * standard initialization. All regular bean definitions will have been loaded,
     * but no beans will have been instantiated yet. This allows for adding further
     * bean definitions before the next post-processing phase kicks in.
     * @param registry the bean definition registry used by the application context
     * @throws org.springframework.beans.BeansException in case of errors
     */
    void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry) throws BeansException;

}

postProcessBeanDefinitionRegistry方法用向bean注册表BeanDefinitionRegistry对象(一般是Spring默认的BeanFacotry对象——DefaultListableBeanFactory)中注册bean的配置信息,即注册BeanDefintion对象。

两类工厂bean的执行顺序

BeanFactoryPostProcessor的postProcessBeanFactory方法在所有的bean的BeanDefinition对象加载到bean注册表中后被调用,而BeanDefinitionRegistryPostProcessor的postProcessBeanDefinitionRegistry方法用于向bean注册表中注册BeanDefinition对象。因此,这两个方法的执行顺序有严格的要求,下面我们通过Spring4的源码解释这个流程。

Spring4执行把通过PostProcessorRegistrationDelegate的静态方法invokeBeanFactoryPostProcessors方法执行工厂后处理器的相关方法,此方法的代码如下。(这段代码有点长,看我的注释就是了)

    public static void invokeBeanFactoryPostProcessors(
            ConfigurableListableBeanFactory beanFactory, List<BeanFactoryPostProcessor> beanFactoryPostProcessors) {

         // 首先执行BeanDefinitionRegistryPostProcessors
        Set<String> processedBeans = new HashSet<String>();

        if (beanFactory instanceof BeanDefinitionRegistry) {
            BeanDefinitionRegistry registry = (BeanDefinitionRegistry) beanFactory;
            List<BeanFactoryPostProcessor> regularPostProcessors = new LinkedList<BeanFactoryPostProcessor>();
            List<BeanDefinitionRegistryPostProcessor> registryPostProcessors =
                    new LinkedList<BeanDefinitionRegistryPostProcessor>();
            // 遍历容器中的工厂后处理器
            for (BeanFactoryPostProcessor postProcessor : beanFactoryPostProcessors) {
                if (postProcessor instanceof BeanDefinitionRegistryPostProcessor) {
                    BeanDefinitionRegistryPostProcessor registryPostProcessor =
                            (BeanDefinitionRegistryPostProcessor) postProcessor;
                    // 执行BeanDefinitionRegistryPostProcessor的
                    // ->postProcessBeanDefinitionRegistry方法
                    registryPostProcessor.postProcessBeanDefinitionRegistry(registry);
                    registryPostProcessors.add(registryPostProcessor);
                }
                else {
                    regularPostProcessors.add(postProcessor);
                }
            }

             // 获取并执行bean工厂中定义的BeanDefinitionRegistryPostProcessor对象,这里分为三步,如下。
            String[] postProcessorNames =
                    beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);

            // 首先,执行实现了PriorityOrdered接口的BeanDefinitionRegistryPostProcessor对象
            List<BeanDefinitionRegistryPostProcessor> priorityOrderedPostProcessors = new ArrayList<BeanDefinitionRegistryPostProcessor>();
            for (String ppName : postProcessorNames) {
                if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) {
                    priorityOrderedPostProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class));
                    processedBeans.add(ppName);
                }
            }
            sortPostProcessors(beanFactory, priorityOrderedPostProcessors);
            registryPostProcessors.addAll(priorityOrderedPostProcessors);
            invokeBeanDefinitionRegistryPostProcessors(priorityOrderedPostProcessors, registry);

            // 然后,执行实现了Ordered接口的BeanDefinitionRegistryPostProcessor对象
            postProcessorNames = beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);
            List<BeanDefinitionRegistryPostProcessor> orderedPostProcessors = new ArrayList<BeanDefinitionRegistryPostProcessor>();
            for (String ppName : postProcessorNames) {
                if (!processedBeans.contains(ppName) && beanFactory.isTypeMatch(ppName, Ordered.class)) {
                    orderedPostProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class));
                    processedBeans.add(ppName);
                }
            }
            sortPostProcessors(beanFactory, orderedPostProcessors);
            registryPostProcessors.addAll(orderedPostProcessors);
            invokeBeanDefinitionRegistryPostProcessors(orderedPostProcessors, registry);

            // 最后执行其它的BeanDefinitionRegistryPostProcessor对象
            boolean reiterate = true;
            while (reiterate) {
                reiterate = false;
                postProcessorNames = beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);
                for (String ppName : postProcessorNames) {
                    if (!processedBeans.contains(ppName)) {
                        BeanDefinitionRegistryPostProcessor pp = beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class);
                        registryPostProcessors.add(pp);
                        processedBeans.add(ppName);
                        pp.postProcessBeanDefinitionRegistry(registry);
                        reiterate = true;
                    }
                }
            }

            // 执行BeanDefinitionRegistryPostProcessor工厂后处理器的postProcessBeanFactory方法
            invokeBeanFactoryPostProcessors(registryPostProcessors, beanFactory);
            // 执行容器中普通的工厂后处理器的postProcessBeanFactory方法
            invokeBeanFactoryPostProcessors(regularPostProcessors, beanFactory);
        } else {
            // 执行容器中的bean工厂后处理器的postProcessBeanFactory方法
            invokeBeanFactoryPostProcessors(beanFactoryPostProcessors, beanFactory);
        }

        // 获取定义在bean工厂中的bean工厂后处理器,下面执行postProcessBeanFactory方法也分成三步,如下。
        String[] postProcessorNames =
                beanFactory.getBeanNamesForType(BeanFactoryPostProcessor.class, true, false);

        // 把bean工厂后处理器按PriorityOrdered、Ordered和其他来分类
        List<BeanFactoryPostProcessor> priorityOrderedPostProcessors = new ArrayList<BeanFactoryPostProcessor>();
        List<String> orderedPostProcessorNames = new ArrayList<String>();
        List<String> nonOrderedPostProcessorNames = new ArrayList<String>();
        for (String ppName : postProcessorNames) {
            if (processedBeans.contains(ppName)) {
                // 排除前面已经执行了的后处理器
            }
            else if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) {
                priorityOrderedPostProcessors.add(beanFactory.getBean(ppName, BeanFactoryPostProcessor.class));
            }
            else if (beanFactory.isTypeMatch(ppName, Ordered.class)) {
                orderedPostProcessorNames.add(ppName);
            }
            else {
                nonOrderedPostProcessorNames.add(ppName);
            }
        }

        // 首先执行实现了PriorityOrdered接口的后处理器
        sortPostProcessors(beanFactory, priorityOrderedPostProcessors);
        invokeBeanFactoryPostProcessors(priorityOrderedPostProcessors, beanFactory);

        // 然后执行实现了Ordered接口的后处理器
        List<BeanFactoryPostProcessor> orderedPostProcessors = new ArrayList<BeanFactoryPostProcessor>();
        for (String postProcessorName : orderedPostProcessorNames) {
            orderedPostProcessors.add(beanFactory.getBean(postProcessorName, BeanFactoryPostProcessor.class));
        }
        sortPostProcessors(beanFactory, orderedPostProcessors);
        invokeBeanFactoryPostProcessors(orderedPostProcessors, beanFactory);

        //  最后执行其他的后处理器
        List<BeanFactoryPostProcessor> nonOrderedPostProcessors = new ArrayList<BeanFactoryPostProcessor>();
        for (String postProcessorName : nonOrderedPostProcessorNames) {
            nonOrderedPostProcessors.add(beanFactory.getBean(postProcessorName, BeanFactoryPostProcessor.class));
        }
        invokeBeanFactoryPostProcessors(nonOrderedPostProcessors, beanFactory);

        // 清除工厂中的元数据缓存
        beanFactory.clearMetadataCache();
    }
    /**
     * 执行给定的BeanDefinitionRegistryPostProcessor beans.
     */
    private static void invokeBeanDefinitionRegistryPostProcessors(
            Collection<? extends BeanDefinitionRegistryPostProcessor> postProcessors, BeanDefinitionRegistry registry) {

        for (BeanDefinitionRegistryPostProcessor postProcessor : postProcessors) {
            postProcessor.postProcessBeanDefinitionRegistry(registry);
        }
    }
    /**
    * 执行给定的bean工厂
    **/
    private static void invokeBeanFactoryPostProcessors(
            Collection<? extends BeanFactoryPostProcessor> postProcessors, ConfigurableListableBeanFactory beanFactory) {

        for (BeanFactoryPostProcessor postProcessor : postProcessors) {
            postProcessor.postProcessBeanFactory(beanFactory);
        }
    }

上面的执行流程用图表达如下。
这里写图片描述

上图很明显的表达了bean工厂后处理器的执行顺序,但这里还有两点需要说明的。

a. 为什么要先执行BeanDefinitionRegistryPostProcessor?因为实现BeanDefinitionRegistryPostProcessor 接口的后处理器可以在bean工厂创建其他bean之前添加更多的BeanDefinition对象到bean工厂中去。比如spring中ConfigurationClassPostProcessor类就是这样一种工厂后处理器,它主要把被@Configuration注解的类中定义的bean信息转换成BeanDefinition对象,并注册到bean工厂中。

b. 这个流程中有一个很明显的规定就是,不管是什么工厂后处理器,都必须先执行容器中的工厂后处理器后,才执行bean工厂中的工厂后处理器。这里的容器中的工厂后处理器是指ApplicationContext对象所持有的未注册到bean工厂中的。bean工厂中的工厂后处理器是指注册到BeanFactory对象中的后处理器。

BeanDefinitionRegistryPostProcessor接口的实现类

spring-context-x.x.x模块下的org.springframework.context.annotation.ConfigurationClassPostProcessor后处理器,用于加载基于java类配置的bean。

mybatis-spring包中的org.mybatis.spring.mapper.MapperScannerConfigurer:用于扫描指定包下的mapper接口。

BeanFactoryPostProcessor接口的实现类

spring-beans-x.x.x模块下的PropertyOverrideConfigurer:加载属性文件中信息直接覆盖Spring配置文件中的元数据。

spring-beans-x.x.x模块下PropertyPlaceholderConfigurer及其子类PreferencesPlaceholderConfigurer:负责读取properties属性文件里的属性值,并将这些属性值设置成Spring配置文件的元数据。

spring-context-x.x.x模块下PropertySourcesPlaceholderConfigurer:和PropertyPlaceholderConfigurer的作用一样,不过前者是spring3.1后<context:property-placeholder/>默认加载。后者是3.1以前默认加载的。

关于上面3个与加载属性文件相关的后处理器如何被引入到Spring容器中,请见解析context命名空间之property-placeholder和property-override标签

spring-beans-x.x.x模块下的CustomScopeConfigurer:用于向BeanFactory中注册自定义bean作用域Scope对象。

spring-beans-x.x.x模块下的CustomEditorConfigurer:用于向BeanFactory中注册自定义的PropertyEditorRegistrar对象和PropertyEditor对象。

<think>好的,我现在需要帮助用户了解Spring框架中前置处理器的功能和作用,以及具体实现。首先,我需要回忆一下Spring的相关知识,确保信息准确。前置处理器Spring中通常指的是BeanPostProcessor接口的实现,特别是它的postProcessBeforeInitialization和postProcessAfterInitialization方法。这两个方法分别在Bean的初始化前后被调用,允许开发者对Bean进行修改或增强。 用户提到的引用中,引用[2]和[3]提到了前置处理器用于在初始化前后进行操作,可能涉及增强、修改或校验Bean实例。引用[4]也提到了类似的内容。我需要确认BeanPostProcessor的正确使用方式和常见应用场景,比如处理AOP代理、属性校验、日志注入等。 接下来,我需要组织回答的结构。首先解释前置处理器的定义和作用,然后说明它的工作原理,接着给出具体实现步骤,包括实现接口、注册处理器等。然后列举常见应用场景,如AOP、属性处理、日志和监控等。同时,需要引用用户提供的参考文献来支持回答,比如引用[2]和[3]提到的前置处理器的用途,引用[4]中的问题可以作为相关问题的参考。 需要注意的是,用户提供的引用中有一些重复和不相关的内容,比如引用[1]主要讲Bean的生命周期和refresh方法,可能与前置处理器关联不大,但可以提到BeanPostProcessor在生命周期中的位置。而引用[3]提到的PropertyOverrideConfigurer可能是一个具体的例子,但需要确认是否正确,因为PropertyOverrideConfigurer实际上是BeanFactoryPostProcessor,属于容器级别的处理,而不是Bean级别的BeanPostProcessor。这里可能存在混淆,需要指出两者的区别,避免用户误解。 因此,在回答中需要明确区分BeanPostProcessor(前置/后置处理器)和BeanFactoryPostProcessor(工厂后置处理器)的不同。BeanPostProcessor作用于Bean实例化之后,初始化前后,而BeanFactoryPostProcessor作用于Bean定义加载之后,实例化之前,用来修改Bean的定义。 最后,按照用户的要求生成相关问题,这些问题应该围绕前置处理器的实现细节、应用场景、与其他处理器的区别等方面展开,帮助用户深入理解。 总结步骤: 1. 定义前置处理器及其作用。 2. 解释其在Bean生命周期中的位置。 3. 具体实现步骤,包括接口方法和注册方式。 4. 常见应用场景举例。 5. 与其他处理器(如BeanFactoryPostProcessor)的区别。 6. 引用相关文献支持内容。 7. 生成相关问题,促进进一步学习。</think>### Spring框架中前置处理器的功能与实现解析 #### 一、前置处理器的定义与作用 **前置处理器**(BeanPostProcessor)是Spring框架中用于干预Bean生命周期的重要接口,主要在Bean初始化**前后**执行自定义逻辑。其核心作用包括: 1. **Bean实例增强**:动态修改Bean属性或代理对象(如AOP实现)[^2] 2. **校验与监控**:检查Bean状态合法性,收集运行时指标 3. **资源注入**:实现特殊依赖注入逻辑(如加密配置解密) #### 二、工作原理与执行时机 在Bean生命周期中的关键节点: $$ \begin{aligned} &\text{实例化} \rightarrow \text{属性填充} \rightarrow \text{前置处理} \rightarrow \text{初始化} \\ &\rightarrow \text{后置处理} \rightarrow \text{加入容器} \end{aligned} $$ 具体执行流程: 1. `postProcessBeforeInitialization()`:在`init-method`/`@PostConstruct`之前执行 2. `postProcessAfterInitialization()`:在初始化方法之后执行 #### 三、具体实现步骤 1. **实现接口**: ```java public class CustomProcessor implements BeanPostProcessor { @Override public Object postProcessBeforeInitialization(Object bean, String beanName) { // 例如:自动添加日志能力 if(bean instanceof Service) { return enhanceWithLogging(bean); } return bean; } } ``` 2. **注册处理器**: ```xml <bean class="com.example.CustomProcessor"/> ``` 或使用注解: ```java @Component public class CustomProcessor implements BeanPostProcessor {...} ``` #### 四、典型应用场景 1. **AOP代理生成**:`AbstractAutoProxyCreator`通过后置处理实现动态代理[^1] 2. **属性占位符处理**:`AutowiredAnnotationBeanPostProcessor`处理`@Autowired` 3. **配置加密解密**:自动解密被加密的数据库密码字段 4. **接口版本控制**:根据运行时环境动态替换实现类 #### 五、注意事项 1. **作用范围**:会作用于**所有**Bean,需通过`beanName`或类型过滤 2. **执行顺序**:可通过`Ordered`接口或`@Order`注解控制 3. **与BeanFactoryPostProcessor区别**:后者修改Bean定义(元数据阶段),前置处理器修改Bean实例[^3]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值