Spring源码–BeanFactoryPostProcessor

对于BeanFactoryPostProcessor下面是官方api文档给出的定义:

连接工厂允许修改自定义应用的bean信息,可以调整底层bean工厂的属性值。(Factory hook that allows for custom modification of an application context's bean definitions, adapting the bean property values of the context's underlying bean factory.)

从上面 的文档上看就是可以修改bean信息,但是修改的触发节点是在bean实例化前才会有效果 。看下BeanFactoryPostProcessor的源码:

public interface BeanFactoryPostProcessor {
void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException;

}

从源码中可以看出,这个接口只有一个接口,所有的实现都是集成这个接口,下面 是实现接口的对应类型。

2-3.spring源码--BeanFactoryPostProcessor_ide

下面看下这个其中一个的源码:

public BeanFactoryPostProcessor beanFactoryPostProcessor() {
return new BeanFactoryPostProcessor() {
@Override
public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) {
BeanDefinition bd = beanFactory.getBeanDefinition("beanPostProcessor");
bd.getPropertyValues().addPropertyValue("nameSuffix", "-processed-" + myProp);
}
};
}

以上核心代码只有两个句,第一步:BeanDefinition bd = beanFactory.getBeanDefinition(“beanPostProcessor”);通过bean工厂 获取到BeanDefinition的对象。第二步:bd.getPropertyValues().addPropertyValue(“nameSuffix”, “-processed-” + myProp);对于bean加入 属性。

下面我们举个栗子,看下BeanFactoryPostProcessor使用情况:

集成BeanFactoryPostProcessor接口,实现重写postProcessBeanFactory方法:

public class NameBeanFactoryPostProcessor implements BeanFactoryPostProcessor {
@Override
public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
System.out.println("-->NameBeanFactoryPostProcessor start");
String[] names = beanFactory.getBeanDefinitionNames();
for (String name : names) {
if("a".equals(name)){

BeanDefinition beanDefinition = beanFactory.getBeanDefinition(name);
MutablePropertyValues propertyValues = beanDefinition.getPropertyValues();
if(propertyValues.contains("name")){
propertyValues.addPropertyValue("name", "王五");
System.out.println("-->mod bean definition name");
}
}
}
System.out.println("-->NameBeanFactoryPostProcessor end");
}
}

执行触发方法:

public class TestAB {
public static void main(String[] args) {
ApplicationContext applicationContext= new ClassPathXmlApplicationContext("x.xml");
A a=applicationContext.getBean(A.class);
System.out.println("-->NameBeanFactoryPostProcessor test end!");
System.out.println("-->name :"+ a.getName());
}
}

看下A类的xml的文件内容:

<bean id="a" class="org.springframework.test.debug.A">
<property name="name" value="张三"></property>
</bean>

执行结果:

-->NameBeanFactoryPostProcessor start
-->mod bean definition name
-->NameBeanFactoryPostProcessor end
-->BeanFactoryPostProcessor test end!
-->name :王五

A类的属性被修改了 , 从张三 -> 王五。

下面思考一个问题,如果有多个BeanFactoryPostProcessor存在怎么办?

这时候给A类加一个age属性,再添加AgeBeanFactoryPostProcessor,这时有两个BeanFactoryPostProcessor,这时就用到了我们之前降到的AbstractApplicationContext实现类中的refresh方法,在refresh方法中有进行,回顾一下refresh方法与beanFactory相关的四个方法:

//创建
ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();
//准备
prepareBeanFactory(beanFactory);
//空方法
postProcessBeanFactory(beanFactory);
//处理逻辑
invokeBeanFactoryPostProcessors(beanFactory);

进入invokeBeanFactoryPostProcessors(beanFactory)展示源码:

protected void invokeBeanFactoryPostProcessors(ConfigurableListableBeanFactory beanFactory) {
//逻辑处理
PostProcessorRegistrationDelegate.invokeBeanFactoryPostProcessors(beanFactory, getBeanFactoryPostProcessors());
//后续处理
if (beanFactory.getTempClassLoader() == null && beanFactory.containsBean(LOAD_TIME_WEAVER_BEAN_NAME)) {
beanFactory.addBeanPostProcessor(new LoadTimeWeaverAwareProcessor(beanFactory));
beanFactory.setTempClassLoader(new ContextTypeMatchClassLoader(beanFactory.getBeanClassLoader()));
}
}

在进入PostProcessorRegistrationDelegate.invokeBeanFactoryPostProcessors(beanFactory, getBeanFactoryPostProcessors());方法中,查看源码

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

//......省略了部分代码,代码太长了,了解这块内容看这里就行了

// First, invoke the BeanFactoryPostProcessors that implement PriorityOrdered.
//首先,调用实现 PriorityOrdered 的 BeanFactoryPostProcessor。
sortPostProcessors(priorityOrderedPostProcessors, beanFactory);
invokeBeanFactoryPostProcessors(priorityOrderedPostProcessors, beanFactory);

// Next, invoke the BeanFactoryPostProcessors that implement Ordered.
//接下来,调用实现 Ordered 的 BeanFactoryPostProcessors。
List<BeanFactoryPostProcessor> orderedPostProcessors = new ArrayList<>(orderedPostProcessorNames.size());
for (String postProcessorName : orderedPostProcessorNames) {
orderedPostProcessors.add(beanFactory.getBean(postProcessorName, BeanFactoryPostProcessor.class));
}
sortPostProcessors(orderedPostProcessors, beanFactory);
invokeBeanFactoryPostProcessors(orderedPostProcessors, beanFactory);

// Finally, invoke all other BeanFactoryPostProcessors.
//最后,调用所有其他 BeanFactoryPostProcessor。
List<BeanFactoryPostProcessor> nonOrderedPostProcessors = new ArrayList<>(nonOrderedPostProcessorNames.size());
for (String postProcessorName : nonOrderedPostProcessorNames) {
nonOrderedPostProcessors.add(beanFactory.getBean(postProcessorName, BeanFactoryPostProcessor.class));
}
invokeBeanFactoryPostProcessors(nonOrderedPostProcessors, beanFactory);
}

在上面源码中可以看出,在执行优先级 实现PriorityOrdered > 实现Ordered > 其他 。所以PriorityOrdered 和Ordered 是影响BeanFactoryPostProcessors执行顺序的最终因素。下面看下PriorityOrdered 和Ordered 源码:

public interface PriorityOrdered extends Ordered {
}

public interface Ordered {

int HIGHEST_PRECEDENCE = Integer.MIN_VALUE;

int LOWEST_PRECEDENCE = Integer.MAX_VALUE;

/**
* Get the order value of this object.
* <p>Higher values are interpreted as lower priority. As a consequence,
* the object with the lowest value has the highest priority (somewhat
* analogous to Servlet {@code load-on-startup} values).
* <p>Same order values will result in arbitrary sort positions for the
* affected objects.
* @return the order value
* @see #HIGHEST_PRECEDENCE
* @see #LOWEST_PRECEDENCE
*/
int getOrder();

}

从源码上可以看出来PriorityOrdered是继承了Ordered接口,所以下面我们以Ordered接口为例,去验证多个BeanFactoryPostProcessors类。

NameBeanFactoryPostProcessor类

public class NameBeanFactoryPostProcessor implements BeanFactoryPostProcessor, Ordered {
@Override
public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
System.out.println("-->NameBeanFactoryPostProcessor start");
String[] names = beanFactory.getBeanDefinitionNames();
for (String name : names) {
if("a".equals(name)){

BeanDefinition beanDefinition = beanFactory.getBeanDefinition(name);
MutablePropertyValues propertyValues = beanDefinition.getPropertyValues();
if(propertyValues.contains("name")){
propertyValues.addPropertyValue("name", "王五");
System.out.println("-->mod bean definition name");
}
}
}
System.out.println("-->NameBeanFactoryPostProcessor end");
}

@Override
public int getOrder() {
return 1;
}
}

AgeBeanFactoryPostProcessor类

public class AgeBeanFactoryPostProcessor implements BeanFactoryPostProcessor, Ordered {
@Override
public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
System.out.println("-->AgeBeanFactoryPostProcessor start");
String[] names = beanFactory.getBeanDefinitionNames();
for (String name : names) {
if("a".equals(name)){

BeanDefinition beanDefinition = beanFactory.getBeanDefinition(name);
MutablePropertyValues propertyValues = beanDefinition.getPropertyValues();
if(propertyValues.contains("name")){
propertyValues.addPropertyValue("age", 12);
System.out.println("-->mod bean definition age");
}
}
}
System.out.println("-->AgeBeanFactoryPostProcessor end");
}

@Override
public int getOrder() {
return 2;
}
}

x.xml文件

<bean id="a" class="org.springframework.test.debug.A">
<property name="name" value="张三"></property>
<property name="age" value="16"></property>
</bean>
<!-- 注册BeanFactoryPostProcessor -->
<bean class="org.springframework.test.debug.NameBeanFactoryPostProcessor"></bean>
<bean class="org.springframework.test.debug.AgeBeanFactoryPostProcessor"></bean>

启动方法

public static void main(String[] args) {
ApplicationContext applicationContext= new ClassPathXmlApplicationContext("x.xml");
A a=applicationContext.getBean(A.class);
System.out.println("-->BeanFactoryPostProcessor test end!");
System.out.println("-->name :"+ a.getName());
System.out.println("-->age :"+ a.getAge());
}

执行结果

-->NameBeanFactoryPostProcessor start
-->mod bean definition name
-->NameBeanFactoryPostProcessor end
-->AgeBeanFactoryPostProcessor start
-->mod bean definition age
-->AgeBeanFactoryPostProcessor end
-->BeanFactoryPostProcessor test end!
-->name :王五
-->age :12

从输出结果上看确实是先执行的NameBeanFactoryPostProcessor,后置执行的AgeBeanFactoryPostProcessor,与设置的order数字是一致的。

坚持吧!!! 坚持卷spring源码