BeanFactoryPostProcessor

1 使用

示例:去除Spring容器中潜在的敏感词信息,例如bean定义中过滤"zxt"、"sb"等词。

1.1 XML文件

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
       http://www.springframework.org/schema/beans/spring-beans.xsd">

    <bean id="customBeanFactoryPost" class="com.test.CustomBeanFactoryPostProcessor">
        <property name="obs">
            <set>
                <value>zxt</value>
                <value>sb</value>
            </set>
        </property>
    </bean>
    <bean id="u1" class="com.test.UserPO" >
        <property name="userName" value="sb" />
        <property name="email" value="zxt@163.com" />
        <property name="address" ref="testAddr" />
    </bean>
    <bean id="testAddr" class="com.test.Address" >
        <property name="desc" value="testDesc" />
        <property name="detail" value="testDetail" />
    </bean>
</beans>

1.2 POJO:UserPo

public class UserPO {
    private String userName;
    private String email;
    private Address address;
    // setter, getter
}

public class Address {
    private String desc;
    private String detail;
    // setter, getter
}

1.3 BeanFactoryPostProcessor

public class CustomBeanFactoryPostProcessor implements BeanFactoryPostProcessor {
    private Set<String> obs;
    public CustomBeanFactoryPostProcessor() {
        obs = new HashSet<>();
    }

    /// 数据解析
    private StringValueResolver valueResolver = (strVal) -> {
        if (obsContainValue(strVal)) {
            return "******";
        }
        return strVal;
    };

    //将所有bean 的参数中含有 obs 集合中的值进行屏蔽
    @Override
    public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {


        String[] beanNames = beanFactory.getBeanDefinitionNames();
        for (String beanName : beanNames) {
            BeanDefinition bd = beanFactory.getBeanDefinition(beanName);
            BeanDefinitionVisitor visitor = new BeanDefinitionVisitor(valueResolver);
            visitor.visitBeanDefinition(bd);
        }

    }
    private boolean obsContainValue(String value) {
        String strValue = value.toLowerCase();
        return this.obs.contains(strValue);
    }
    public void setObs(Set<String> obs) {
        this.obs.clear();
        for (String ob : obs) {
            this.obs.add(ob.toLowerCase());
        }
    }
}

1.4 测试

public static void main(String[] args) {
    ApplicationContext ac = new ClassPathXmlApplicationContext("custom-post.xml");
    UserPO userPO = (UserPO) ac.getBean("u1");
    System.out.println(userPO);
}

2 源码分析

2.1 简介

BeanFactoryPostProcessor是在AbstractApplicationContext扩展中实现的。在Spring容器实例化Bean之前的操作,是一个容器级别的处理器。

在Spring中使用的${userName}的引用变量就是通过BeanFactoryPostProcessor实现的,即PropertyPlaceholderConfigurer

2.2 源码

AbstractApplicationContext#refresh()方法中,会获取beanFactory的所有BeanFactoryPostProcessor并进行调用

public void refresh() throws BeansException, IllegalStateException {
    // 执行BeanFactory中的所有BeanFactoryPostProcessor
    invokeBeanFactoryPostProcessors(beanFactory);
}

protected void invokeBeanFactoryPostProcessors(ConfigurableListableBeanFactory beanFactory) {
    PostProcessorRegistrationDelegate.invokeBeanFactoryPostProcessors(beanFactory, getBeanFactoryPostProcessors());
    // Detect a LoadTimeWeaver and prepare for weaving, if found in the meantime
    // (e.g. through an @Bean method registered by ConfigurationClassPostProcessor)
    if (beanFactory.getTempClassLoader() == null && beanFactory.containsBean(LOAD_TIME_WEAVER_BEAN_NAME)) {
        beanFactory.addBeanPostProcessor(new LoadTimeWeaverAwareProcessor(beanFactory));
        beanFactory.setTempClassLoader(new ContextTypeMatchClassLoader(beanFactory.getBeanClassLoader()));
    }
}

执行BeanFactoryPostProcessor委托给了PostProcessorRegistrationDelegate类来实现。
对于BeanFactoryPostProcessor的处理分为2种情况:

  • 特殊的BeanDefinitionRegistryPostProcessor
  • 常规的BeanFactoryPostProcessor

无论是哪种情况,都需要考虑两种情况:

  • 硬编码注册后置处理器

    硬编码注册的后处理器主要通过:AbstractApplicationContext#addBeanFactoryPostProcessor()

  • 通过配置注入的后置处理器
public static void invokeBeanFactoryPostProcessors(ConfigurableListableBeanFactory beanFactory, List<BeanFactoryPostProcessor> beanFactoryPostProcessors) {

    Set<String> processedBeans = new HashSet<String>();
    if (beanFactory instanceof BeanDefinitionRegistry) {
        BeanDefinitionRegistry registry = (BeanDefinitionRegistry) beanFactory;
        // 记录通过硬编码方式注册的BeanFactoryPostProcessor
        List<BeanFactoryPostProcessor> regularPostProcessors = new LinkedList<BeanFactoryPostProcessor>();
        // 记录通过硬编码方式注册的BeanDefinitionRegistryPostProcessor
        List<BeanDefinitionRegistryPostProcessor> registryPostProcessors = new LinkedList<BeanDefinitionRegistryPostProcessor>();
        for (BeanFactoryPostProcessor postProcessor : beanFactoryPostProcessors) {
            if (postProcessor instanceof BeanDefinitionRegistryPostProcessor) {
                BeanDefinitionRegistryPostProcessor registryPostProcessor = (BeanDefinitionRegistryPostProcessor) postProcessor;
                registryPostProcessor.postProcessBeanDefinitionRegistry(registry);
                registryPostProcessors.add(registryPostProcessor);
            } else {
                regularPostProcessors.add(postProcessor);
            }
        }
        // 获取所有通过配置文件注入的BeanDefinitionRegistryPostProcessor类
        String[] postProcessorNames = beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);
        
        // 1.执行实现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);
        // 2.执行实现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);
        // 3.执行其他所有的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;
                }
            }
        }
        invokeBeanFactoryPostProcessors(registryPostProcessors, beanFactory);
        invokeBeanFactoryPostProcessors(regularPostProcessors, beanFactory);
    } else {
        invokeBeanFactoryPostProcessors(beanFactoryPostProcessors, beanFactory);
    }

    // 获取所有配置注入的BeanFactoryPostProcessor,并执行
    String[] postProcessorNames = beanFactory.getBeanNamesForType(BeanFactoryPostProcessor.class, true, false);
    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)) {
            // skip - already processed in first phase above
        } 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);
        }
    }
    sortPostProcessors(beanFactory, priorityOrderedPostProcessors);
    invokeBeanFactoryPostProcessors(priorityOrderedPostProcessors, beanFactory);
    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();
}

转载于:https://www.cnblogs.com/wolfdriver/p/10573395.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值