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