在前一篇文章Spring之BeanPostProcessor(后置处理器)介绍的基础上我们来介绍BeanFactoryPostProcessor接口,从名字上来看很相似,但他们的作用确不尽相同。
文章目录
BeanFactoryPostProcessor
1.BeanFactoryPostProcessor接口内容
2.自定义BeanFactoryPostProcessor 实现类
3.配置文件中注册
4.测试
BeanFactoryPostProcessor
Spring IoC容器允许BeanFactoryPostProcessor在容器实例化任何bean之前读取bean的定义(配置元数据),并可以修改它。同时可以定义BeanFactoryPostProcessor,通过设置’order’属性来确定各个BeanFactoryPostProcessor执行顺序。
注册一个BeanFactoryPostProcessor实例需要定义一个Java类来实现BeanFactoryPostProcessor接口,并重写该接口的postProcessorBeanFactory方法。通过beanFactory可以获取bean的定义信息,并可以修改bean的定义信息。这点是和BeanPostProcessor最大区别,案例代码在上篇文章的基础上验证。
1.BeanFactoryPostProcessor接口内容
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; }
2.自定义BeanFactoryPostProcessor 实现类
/** * 自定义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 执行结束"); } }
3.配置文件中注册
<?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>
4.测试
@Test public void test1() { ApplicationContext ac = new ClassPathXmlApplicationContext("applicationContext.xml"); User user = ac.getBean(User.class); System.out.println(user); }
输出结果
总结:从输出结果我们可以看出postProcessBeanFactory方法执行的顺序是在Bean实例化之前。可以修改Bean的属性值【波波烤鸭改为bobo】。从这儿也能看出BeanFactoryPostProcessor和BeanPostProcessor的区别。