Spring IoC容器允许BeanFactoryPostProcessor在容器实例化任何bean之前读取bean的定义(配置元数据),并可以修改它。同时可以定义BeanFactoryPostProcessor,通过设置’order’属性来确定各个BeanFactoryPostProcessor执行顺序。 注册一个BeanFactoryPostProcessor实例需要定义一个Java类来实现BeanFactoryPostProcessor接口,并重写该接口的postProcessorBeanFactory方法。通过beanFactory可以获取bean的定义信息,并可以修改bean的定义信息。这点是和BeanPostProcessor最大区别,案例代码在上篇文章的基础上验证。
public interface BeanFactoryPostProcessor {
/**
* Modify the application context's internal bean factory after its standard
* initialization. All bean definitions will have been loaded, but no beans
* will have been instantiated yet. This allows for overriding or adding
* properties even to eager-initializing beans.
* @param beanFactory the bean factory used by the application context
* @throws org.springframework.beans.BeansException in case of errors
*/
void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException;
}
/**
* 自定义BeanFactoryPostProcessor
*
* @author dengp
*
*/
public class MyBeanFactoryPostProcessor implements BeanFactoryPostProcessor {
/**
* 本方法在Bean对象实例化之前执行,
* 通过beanFactory可以获取bean的定义信息,
* 并可以修改bean的定义信息。这点是和BeanPostProcessor最大区别
*/
@Override
public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
System.out.println(">> BeanFactoryPostProcessor 开始执行了");
String[] names = beanFactory.getBeanDefinitionNames();
for (String name : names) {
if("user".equals(name)){
BeanDefinition beanDefinition = beanFactory.getBeanDefinition(name);
MutablePropertyValues propertyValues = beanDefinition.getPropertyValues();
// MutablePropertyValues如果设置了相关属性,可以修改,如果没有设置则可以添加相关属性信息
if(propertyValues.contains("name")){
propertyValues.addPropertyValue("name", "bobo");
System.out.println("修改了属性信息");
}
}
}
System.out.println(">> BeanFactoryPostProcessor 执行结束");
}
}
<?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 class="com.dpb.pojo.User" id="user" init-method="start">
<property name="name" value="波波烤鸭"></property>
</bean>
<!-- 注册处理器 -->
<bean class="com.dpb.processor.MyBeanPostProcessor"/>
<!-- 注册BeanFactoryPostProcessor -->
<bean class="com.dpb.factoryprocessor.MyBeanFactoryPostProcessor"></bean>
</beans>
@Test
public void test1() {
ApplicationContext ac = new ClassPathXmlApplicationContext("applicationContext.xml");
User user = ac.getBean(User.class);
System.out.println(user);
}
输出结果
>> BeanFactoryPostProcessor 开始执行了
修改了属性信息
>> BeanFactoryPostProcessor 执行结束
User 被实例化
设置:bobo
A before--实例化的bean对象:User [id=0, name=bobo, beanName=null] user
User 中自定义的初始化方法
A after...实例化的bean对象:User [id=0, name=bobo, beanName=null] user
User [id=0, name=bobo, beanName=null]
总结:从输出结果我们可以看出postProcessBeanFactory方法执行的顺序是在Bean实例化之前。可以修改Bean的属性值【波波烤鸭改为bobo】。从这儿也能看出BeanFactoryPostProcessor和BeanPostProcessor的区别。