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.propertiesvalue>
list>
property>
bean>
把PropertyPlaceholderConfigurer这个类间接继承了BeanFactoryPostProcessor接口,当Spring加载任何实现了这个接口的bean的配置时,都会在beanDefinition载入之后执行postProcessorBeanFactory方法.在PropertyPlaceholderConfigurer中实现了postProcessorBeanFactory方法,在方法中调用了mergeProperties(得到配置)、convertProperties(得到的配置转化为合适的类型)、processProperties(将配置内容告知BeanFactory)这3个方法.
2、使用自定义BeanFactoryPostProcessor
比如我们以实现一个BeanFactoryPostProcessor,去除潜在的“流氓”属性值的功能展示自定义BeanFactoryPostProcessor的创建及使用:
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);
}
}
<bean id="bfpp" class="com.ipluto.demo.ObscenityRemovingBeanFactoryPostProcessor">
<constructor-arg>
<set>
<value>bollockesvalue>
<value>winkyvalue>
<value>bumvalue>
<value>Microsoftvalue>
set>
constructor-arg>
bean>
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;
}
}
<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"));
}
使用后处理器,很好的屏蔽掉了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的顺序调用