zoukankan      html  css  js  c++  java
  • Spring的BeanFactoryPostProcessor和BeanPostProcessor

    PostProcessor:后处理器; 
    BeanPostProcessor:Bean的后置处理器(处理的对象是Bean); 
    BeanFactoryPostProcessor:BeanFactory的后置处理器(处理的对象是BeanFactory)

    (1)看一下BeanFactoryPostProcessor接口的源码:

    @FunctionalInterface
    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;
    }
    

    ①方法postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory)的作用是什么? 
    源码中是这样说明的:

    //Modify the application context's internal bean factory after its standard initialization.

    bean factory已经经历了standard initialization; 
    方法的入参ConfigurableListableBeanFactory beanFactory即是standard initialization后的bean factory; 
    把standard initialization后的bean factory交给我们处理,我们可以对其进行修改。 
    ②什么时候调用postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory)? 
    源码中是这样说明的:

    // All bean definitions will have been loaded, but no beans will have been instantiated yet.

    bean factory已经经历了standard initialization,所有的bean definitions也已经被加载到bean factory之中,但是还没有创建(实例化)任何的Bean。 
    ③方法的入参beanFactory 
    方法的入参ConfigurableListableBeanFactory beanFactory即是我们需要处理的对象;beanFactory已经经历了standard initialization,所有的bean definitions也已经被加载到beanFactory之中。 
    ④如何操作(处理)beanFactory呢? 
    操作beanFactory的常见方式: 
    对加载到beanFactory中的bean definitions进行修改。

    通过参数beanFactory,可以获取相关Bean的bean definition,并修改bean definition。

    (2)代码示例: 
    User类:

    public class User {
        private String username;
        private int age;
    
        public void setUsername(String username) {
            System.out.println("setUsername()");
            this.username = username;
        }
    
        public void setAge(int age) {
            System.out.println("setAge()");
            this.age = age;
        }
    
        public User(){
            System.out.println("Constructor()");
        }
    
        @Override
        public String toString() {
            return "User [username=" + username + ", age=" + age + "]";
        }
    
    }

    BeanFactoryPostProcessor处理器:

    public class MyBeanFactoryPostProcessor implements BeanFactoryPostProcessor {
        public MyBeanFactoryPostProcessor(){
            System.out.println("BeanFactoryPostProcessor实现类的构造器");
        }
    
        @Override
        public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
            System.out.println("BeanFactoryPostProcessor.postProcessBeanFactory()");
    
            //获取指定的BeanDefinition
            BeanDefinition bd = beanFactory.getBeanDefinition("user1");
            //根据BeanDefinition获取MutablePropertyValues
            MutablePropertyValues pvs = bd.getPropertyValues();
    
            //增加
            pvs.add("age", 20);
            //覆盖
            pvs.add("username", "Richard");
        }
    }
    

    Bean配置文件:

        <bean id="user1" class="com.User">
            <!-- 这里只为属性username赋值,属性age没有赋值 -->
            <property name="username" value="Jack"></property>
        </bean>
    
        <bean class="com.MyBeanFactoryPostProcessor"></bean>

    测试类:

        public static void main(String[] args) {
            ApplicationContext context=new ClassPathXmlApplicationContext("applicationContext.xml");
    
            User user1=(User)context.getBean("user1");
            System.out.println(user1);
        }
    

    运行结果: 

    BeanFactoryPostProcessor实现类的构造器 
    BeanFactoryPostProcessor.postProcessBeanFactory() 
    Constructor() 
    setUsername() 
    setAge() 
    User [username=Richard, age=20]

    (3)注意点: 
    BeanFactoryPostProcessor接口和BeanPostProcessor接口非常相似,都是spring初始化bean时对外暴露的扩展点。

    ①BeanFactory的后置处理器:Spring提供的一种特殊的Bean 
    ②BeanFactory的后置处理器,需要实现BeanFactoryPostProcessor接口 
    ③需要在Bean的配置文件中,注册BeanFactory的后置处理器,但不需要设置id属性。IOC容器会自动识别这是个BeanFactory的后置处理器,自动的使用它。

    <bean class="com.MyBeanFactoryPostProcessor"></bean>

    ④实例化BeanFactoryPostProcessor实现类,并调用BeanFactoryPostProcessor的postProcessBeanFactory()方法; 
    这2步会很早进行,在Bean实例被创建之前进行。 
    ⑤Bean的后置处理器,操作的对象是Bean,会对容器中的所有Bean进行处理,每个Bean都要经过2个处理方法postProcessBeforeInitialization()和postProcessAfterInitialization(); 
    BeanFactory的后置处理器,操作的对象是BeanFactory,因此只会有一次处理过程(很早进行,在Bean实例被创建之前进行),即只调用处理方法postProcessBeanFactory()一次。

  • 相关阅读:
    84. Largest Rectangle in Histogram (Solution 2)
    84. Largest Rectangle in Histogram (Solution 1)
    73. Set Matrix Zeroes
    【JavaScript】Symbol 静态方法
    【JavaScript】Date
    【JavaScript】Math
    725. Split Linked List in Parts把链表分成长度不超过1的若干部分
    791. Custom Sort String字符串保持字母一样,位置可以变
    508. Most Frequent Subtree Sum 最频繁的子树和
    762. Prime Number of Set Bits in Binary Representation二进制中有质数个1的数量
  • 原文地址:https://www.cnblogs.com/taiwan/p/7868725.html
Copyright © 2011-2022 走看看