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()一次。

  • 相关阅读:
    只因写了一段爬虫,公司200多人被抓!
    中国顶级程序员图鉴
    漫画 | 外行对程序员误会有多深!
    关于深夜技术事故纪实录的若干问题回复
    富士康14跳被我赶上了,流水线车间真的没有梦想 | 十年系列
    祖国和我们小山村的希望
    互联网从此没有 BAT
    程序员,职场上请远离这种人!
    HTML5漂亮实用的电子书
    这个jQuery导航菜单怎么样
  • 原文地址:https://www.cnblogs.com/taiwan/p/7868725.html
Copyright © 2011-2022 走看看