Spring之BeanFactoryPostProcessor接口介绍


 在前一篇文章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);
}

输出结果

>> 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的区别。


上一篇:Java并发编程:Thread类的使用


下一篇:alipay.trade.refund(统一收单交易退款接口)如何判断退款是否成功