BeanFactoryPostProcessor

BeanFactory是Spring中容器功能的基础,用于存放所有已经加载的bean,为了保证程序上的高可扩展性,Spring针对BeanFactory做了大量的扩展.

激活注册BeanFactoryPostProcessor

BeanFactoryPostProcessor和BeanPostProcessor类似,可以对beanDefinition进行处理,也就是说SpringIOC容器允许BeanFactoryPostProcessor在容器实际实例化任何bean之前读取beanDefinition,并有可能修改他.并且我们还可以配置自定义的BeanFactoryPostProcessor.如果想改变bean,那么使用beanPostProcessor.

并通过order属性来控制BeanFactoryPostProcessor的执行次序.因为只有实现了Ordered接口时,才可以设置这个属性,所以在实现BeanFactoryPostProcessor的时候,就应该考虑实现Ordered接口.

BeanFactoryPostProcessor的作用域是容器级的,只和你使用的容器有关,如果在一个容器中定义了一个BeanFactoryPostProcessor,他仅仅对此容器中的beanDefinition进行后处理.BeanFactoryPostProcessor不会对定义在另一个容器中的bean进行后处理,即便这两个容器都在同一个层次上.

1、BeanFactoryPostProcessor的典型应用:PropertyPlaceholderConfigurer
有时候我们在Spring的bean的描述文件中需要引入像properties配置文件中数据举个例子:

<bean id="black" class="com.ipluto.demo.BlackCat">
    <property name="name">
        <value>${cat.name}</value>
    </property>
</bean>

注意上面使用了一个${cat.name},这就是Spring的分散配置,可以在另外的配置文件中为cat.name指定值,比如在cat.properties配置文件中配置:

cat.name = 火锅

在访问BlackCat的时候,name属性就会被替换为“火锅”,这就是PropertyPlaceholderConfigurer的功能.

<bean id="nameHandler" class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
    <property name="locations">
        <list>
            <value>config/cat.properties</value>
        </list>
    </property>
</bean>

把PropertyPlaceholderConfigurer这个类间接继承了BeanFactoryPostProcessor接口,当Spring加载任何实现了这个接口的bean的配置时,都会在beanDefinition载入之后执行postProcessorBeanFactory方法.在PropertyPlaceholderConfigurer中实现了postProcessorBeanFactory方法,在方法中调用了mergeProperties(得到配置)、convertProperties(得到的配置转化为合适的类型)、processProperties(将配置内容告知BeanFactory)这3个方法.

2、使用自定义BeanFactoryPostProcessor
比如我们以实现一个BeanFactoryPostProcessor,去除潜在的“流氓”属性值的功能展示自定义BeanFactoryPostProcessor的创建及使用:

  • 自定义一个postProcessor
public class ObscenityRemovingBeanFactoryPostProcessor implements BeanFactoryPostProcessor {

    private Set<String> obscenity;


    public ObscenityRemovingBeanFactoryPostProcessor(Set<String> obscenity) {
        this.obscenity = obscenity;
    }

    @Override
    public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
        String[] beanDefinitionNames = beanFactory.getBeanDefinitionNames();
        for (String beanDefinitionName : beanDefinitionNames) {
            BeanDefinition beanDefinition = beanFactory.getBeanDefinition(beanDefinitionName);
            // 创建了一个string类型的解析器
            StringValueResolver stringValueResolver = new StringValueResolver() {
                @Override
                public String resolveStringValue(String strVal) {
                    if (isObscene(strVal))
                        return "*****";
                    return strVal;
                }
            };
            // 构建beanDefinition解析器
            BeanDefinitionVisitor beanDefinitionVisitor = new BeanDefinitionVisitor(stringValueResolver);
            // 使用beanDefinition解析器
            beanDefinitionVisitor.visitBeanDefinition(beanDefinition);
        }

    }

    private boolean isObscene(String strVal) {
        String s = strVal.toString().toUpperCase();
        return obscenity.contains(s);
    }
}

  • 添加到Spring中
<bean id="bfpp" class="com.ipluto.demo.ObscenityRemovingBeanFactoryPostProcessor">
    <constructor-arg>
        <set>
            <value>bollockes</value>
            <value>winky</value>
            <value>bum</value>
            <value>Microsoft</value>
        </set>
    </constructor-arg>
</bean>
  • 定义一个pojo
package com.ipluto.demo;

public class SimplePO {

    private String connectionString;

    private String password;

    private String userName;

    public String getConnectionString() {
        return connectionString;
    }

    public void setConnectionString(String connectionString) {
        this.connectionString = connectionString;
    }

    public String getPassword() {
        return password;
    }

    public void setPassword(String password) {
        this.password = password;
    }

    public String getUserName() {
        return userName;
    }

    public void setUserName(String userName) {
        this.userName = userName;
    }
}

  • 添加到Spring中
<bean id="simpleBean" class="com.ipluto.demo.SimplePO">
    <property name="connectionString" value="bollockes"/>
    <property name="password" value="guest"/>
    <property name="userName" value="Microsoft"/>
</bean>
  • 测试
public static void main(String[] args) {
        ConfigurableListableBeanFactory bf = new XmlBeanFactory(new ClassPathResource("META-INF/beanFactory.xml"));
        BeanFactoryPostProcessor bfpp =(BeanFactoryPostProcessor) bf.getBean("bfpp");
        bfpp.postProcessBeanFactory(bf);
        System.out.println(bf.getBean("simpleBean"));
    }
  • 结果
    SimplePO{connectionString=,userName=,password=guest}

使用后处理器,很好的屏蔽掉了obscenties定义的不应该出现的属性

3、激活BeanFactoryPostProcessor

    protected void invokeBeanFactoryPostProcessors(ConfigurableListableBeanFactory beanFactory) {
        // 激活的核心代码
        PostProcessorRegistrationDelegate.invokeBeanFactoryPostProcessors(beanFactory, 
        // 硬编码注册的后处理器
        this.getBeanFactoryPostProcessors());
        if (!NativeDetector.inNativeImage() && beanFactory.getTempClassLoader() == null && beanFactory.containsBean("loadTimeWeaver")) {
            beanFactory.addBeanPostProcessor(new LoadTimeWeaverAwareProcessor(beanFactory));
            beanFactory.setTempClassLoader(new ContextTypeMatchClassLoader(beanFactory.getBeanClassLoader()));
        }

    }
public static void invokeBeanFactoryPostProcessors(ConfigurableListableBeanFactory beanFactory, List<BeanFactoryPostProcessor> beanFactoryPostProcessors) {
        Set<String> processedBeans = new HashSet();
        ArrayList regularPostProcessors;
        ArrayList registryProcessors;
        int var9;
        ArrayList currentRegistryProcessors;
        String[] postProcessorNames;
        // 对BeanDefinitionRegistry类型的处理
        if (beanFactory instanceof BeanDefinitionRegistry) {
            BeanDefinitionRegistry registry = (BeanDefinitionRegistry)beanFactory;
            regularPostProcessors = new ArrayList();
            registryProcessors = new ArrayList();
            Iterator var6 = beanFactoryPostProcessors.iterator();

            while(var6.hasNext()) {
                BeanFactoryPostProcessor postProcessor = (BeanFactoryPostProcessor)var6.next();
                if (postProcessor instanceof BeanDefinitionRegistryPostProcessor) {
                    BeanDefinitionRegistryPostProcessor registryProcessor = (BeanDefinitionRegistryPostProcessor)postProcessor;
                    // 对于BeanDefinitionRegistryPostProcessor类型,在beanFactoryPostProcessor的基础上还有自定义的方法:postProcessBeanDefinitionRegistry,需要先调用
                    registryProcessor.postProcessBeanDefinitionRegistry(registry);
                    registryProcessors.add(registryProcessor);
                } else {
                	// 常规的beanFactoryPostProcessor
                    regularPostProcessors.add(postProcessor);
                }
            }

            currentRegistryProcessors = new ArrayList();
            // 配置注册的后处理器
            postProcessorNames = beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);
            String[] var16 = postProcessorNames;
            var9 = postProcessorNames.length;

            int var10;
            String ppName;
            for(var10 = 0; var10 < var9; ++var10) {
                ppName = var16[var10];
                // 是PriorityOrdered.class类型的
                if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) {
                    // 收集BeanDefinitionRegistryPostProcessor类型的postProcessor
                    currentRegistryProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class));
                    processedBeans.add(ppName);
                }
            }
			// 排序,根据上面的判断条件:beanFactory.isTypeMatch(ppName, PriorityOrdered.class
			// 可知是根据PriorityOrdered.class排序
            sortPostProcessors(currentRegistryProcessors, beanFactory);
            registryProcessors.addAll(currentRegistryProcessors);
            // 激活,其实就是上面提到的BeanDefinitionRegistryPostProcessor类型的postProcessor,
            // 并且会执行他的自定义方法postProcessBeanDefinitionRegistry
            invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry, beanFactory.getApplicationStartup());
            currentRegistryProcessors.clear();
            // 基本同上,只是下面排序和获取的类型不一样
            postProcessorNames = beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);
            var16 = postProcessorNames;
            var9 = postProcessorNames.length;

            for(var10 = 0; var10 < var9; ++var10) {
                ppName = var16[var10];
                // 排除上面的,并且Ordered.class类型的
                if (!processedBeans.contains(ppName) && beanFactory.isTypeMatch(ppName, Ordered.class)) {
                    currentRegistryProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class));
                    processedBeans.add(ppName);
                }
            }
			// 根据beanFactory.isTypeMatch(ppName, Ordered.class:
			// 可以排序时根据order进行的
            sortPostProcessors(currentRegistryProcessors, beanFactory);
            registryProcessors.addAll(currentRegistryProcessors);
            invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry, beanFactory.getApplicationStartup());
            currentRegistryProcessors.clear();
            boolean reiterate = true;

            while(reiterate) {
                reiterate = false;
                postProcessorNames = beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);
                String[] var19 = postProcessorNames;
                var10 = postProcessorNames.length;

                for(int var26 = 0; var26 < var10; ++var26) {
                    String ppName = var19[var26];
                    // 排除上面两种类型,剩余的PostProcessor
                    if (!processedBeans.contains(ppName)) {
                        currentRegistryProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class));
                        processedBeans.add(ppName);
                        reiterate = true;
                    }
                }
				// 进行排序
                sortPostProcessors(currentRegistryProcessors, beanFactory);
                registryProcessors.addAll(currentRegistryProcessors);
                invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry, beanFactory.getApplicationStartup());
                currentRegistryProcessors.clear();
            }
			// 最后分别调用两种类型的postProcessBeanFactory方法
            invokeBeanFactoryPostProcessors((Collection)registryProcessors, (ConfigurableListableBeanFactory)beanFactory);
            invokeBeanFactoryPostProcessors((Collection)regularPostProcessors, (ConfigurableListableBeanFactory)beanFactory);
        } else {
            invokeBeanFactoryPostProcessors((Collection)beanFactoryPostProcessors, (ConfigurableListableBeanFactory)beanFactory);
        }
		// 获取到所有的配置的BeanFactoryPostProcessor
        String[] postProcessorNames = beanFactory.getBeanNamesForType(BeanFactoryPostProcessor.class, true, false);
        regularPostProcessors = new ArrayList();
        registryProcessors = new ArrayList();
        currentRegistryProcessors = new ArrayList();
        postProcessorNames = postProcessorNames;
        int var20 = postProcessorNames.length;

        String ppName;
        for(var9 = 0; var9 < var20; ++var9) {
            ppName = postProcessorNames[var9];
            	// 排除上面已经处理过的
            if (!processedBeans.contains(ppName)) {
            	// 对于PriorityOrdered类型的
                if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) {
                    regularPostProcessors.add(beanFactory.getBean(ppName, BeanFactoryPostProcessor.class));
                } else if (beanFactory.isTypeMatch(ppName, Ordered.class)) {
                	// 对于Ordered类型的
                    registryProcessors.add(ppName);
                } else {
                	// 除了上面两种类型之外的
                    currentRegistryProcessors.add(ppName);
                }
            }
        }
		// 排序
        sortPostProcessors(regularPostProcessors, beanFactory);
        // 执行ostProcessBeanFactory方法
        invokeBeanFactoryPostProcessors((Collection)regularPostProcessors, (ConfigurableListableBeanFactory)beanFactory);
        List<BeanFactoryPostProcessor> orderedPostProcessors = new ArrayList(registryProcessors.size());
        Iterator var21 = registryProcessors.iterator();

        while(var21.hasNext()) {
            String postProcessorName = (String)var21.next();
            orderedPostProcessors.add(beanFactory.getBean(postProcessorName, BeanFactoryPostProcessor.class));
        }

        sortPostProcessors(orderedPostProcessors, beanFactory);
        invokeBeanFactoryPostProcessors((Collection)orderedPostProcessors, (ConfigurableListableBeanFactory)beanFactory);
        List<BeanFactoryPostProcessor> nonOrderedPostProcessors = new ArrayList(currentRegistryProcessors.size());
        Iterator var24 = currentRegistryProcessors.iterator();

        while(var24.hasNext()) {
            ppName = (String)var24.next();
            nonOrderedPostProcessors.add(beanFactory.getBean(ppName, BeanFactoryPostProcessor.class));
        }

        invokeBeanFactoryPostProcessors((Collection)nonOrderedPostProcessors, (ConfigurableListableBeanFactory)beanFactory);
        beanFactory.clearMetadataCache();
    }

总结一下上面的代码:
对于BeanFactoryPostProcessor的处理主要分为两种情况,一个是对BeanDefinitionRegistry类的处理,另一个是对普通的BeanFactoryPostProcessor的处理.对于这两种情况都要考虑硬编码注入和配置注入的后处理器.
对于硬编码注册的后处理器的处理,主要是通过ApplicationContext中的添加处理器方法addBeanFactoryPostProcessor进行添加.

    public void addBeanFactoryPostProcessor(BeanFactoryPostProcessor postProcessor) {
        Assert.notNull(postProcessor, "BeanFactoryPostProcessor must not be null");
        this.beanFactoryPostProcessors.add(postProcessor);
    }

添加的后处理器会存放在beanFactoryPostProcessors中,而在处理器激活的时候会首先检测beanFactoryPostProcessors中是否有数据.
BeanDefinitionRegistryPostProcessor继承了BeanFactoryPostProcessors,不但有BeanFactoryPostProcessor的特性,还有自己定义的方法,也是需要在这里调用的,所以需要从beanFactoryPostProcessors挑出来,然后执行他的postProcessBeanDefinitionRegistry方法的激活.
if (beanFactory instanceof BeanDefinitionRegistry):
这个判断是因为,BeanDefinitionRegistryPostProcessor只对BeanDefinitionRegistry类型的ConfigurableListableBeanFactory有效,如果beanFactory不是BeanDefinitionRegistry,那么就可以忽略BeanDefinitionRegistryPostProcessor.

强调一个点,对于硬编码方式的后处理器是不需要进行排序的,但是配置文件中读取的处理器,Spring并不能保证他的读取顺序,所以为了保证用户的调用顺序的要求,Spring对于后处理器的排序支持PriorityOrdered或者Ordered的顺序调用

  • 6
    点赞
  • 21
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值