zoukankan      html  css  js  c++  java
  • Spring Boot源码(五):BeanFactoryPostProcessor和BeanPostProcessor

    BeanFactoryPostProcessor是spring BeanFactory加载Bean后调用,

    BeanPostProcessor是Bean初始化前后调用。

    BeanFactoryPostProcessor

    通俗地说:BeanFactoryPostProcessor是胚胎中直接基因改造,BeanPostProcessor是出生后去整容。

     上面是refresh()方法的一部分,之前还调用了

    prepareBeanFactory(beanFactory);

     配置beanFactory

    invokeBeanFactoryPostProcessors(beanFactory);

     

     

     这个方法去执行BeanFactoryPostProcessor下的类。包括自己定义的一些类,mybatis 整合spring就是通过这个。但我们写crud是不用这些东西的,只看一个简单的demo:

    新建一个类实现BeanFactoryPostProcessor :

    @Component
    public class MyBeanFactoryPostProcessor implements BeanFactoryPostProcessor {
        @Override
        public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
            GenericBeanDefinition genericBeanDefinition = (GenericBeanDefinition) beanFactory.getBeanDefinition("people");
            genericBeanDefinition.setBeanClass(User.class);
    
            ConstructorArgumentValues constructorArgumentValues = new ConstructorArgumentValues();
            constructorArgumentValues.addIndexedArgumentValue(0,"abc");
            genericBeanDefinition.setConstructorArgumentValues(constructorArgumentValues);
        }
    }
    
    

    实现postProcessBeanFactory()方法,在这个方法中拿到people的beanDefinition,这里用子类去接收,因为子类api更丰富,

    然后修改他的beanClass为User类(注意User类没有注入Spring 容器):

    public class User {
    }

    运行Test main方法:

    public class Test {
        public static void main(String[] args) {
            //通过注解配置类初始化 spring上下文
            AnnotationConfigApplicationContext annotationConfigApplicationContext =
                    new AnnotationConfigApplicationContext(MyConfig.class);
            //还有一种通过xml来初始化 spring上下文,这里就不介绍了。
            //ClassPathXmlApplicationContext
            System.out.println(annotationConfigApplicationContext.getBean("people"));
        }
    }

    输出结果为:

    component.User@4671e53b

    所以我们可以通过BeanFactoryPostProcessor修改beanDefinition。

    其中还有两个属性简单说下

    autowireMode:自动装配模型。可以设置4个值:

    /**
    * Constant that indicates no externally defined autowiring. Note that
    * BeanFactoryAware etc and annotation-driven injection will still be applied.
    */
    int AUTOWIRE_NO = 0;

    /**
    * Constant that indicates autowiring bean properties by name
    * (applying to all bean property setters).
    */
    int AUTOWIRE_BY_NAME = 1;

    /**
    * Constant that indicates autowiring bean properties by type
    * (applying to all bean property setters).
    */
    int AUTOWIRE_BY_TYPE = 2;

    /**
    * Constant that indicates autowiring the greediest constructor that
    * can be satisfied (involves resolving the appropriate constructor).
    */
    int AUTOWIRE_CONSTRUCTOR = 3;

    默认是0,不自动装配。
    如果设置为1,2。那么该类下的依赖不需要@Autowired或@Resource注解了
    @Component
    public class People {
        private User user;
    }

    对people的beanDefinition设置自动装配,则user也可以正常使用,而不会NPE。


    constructorArgumentValues:
    这个参数会决定bean实例化时调用的构造方法,默认是无参构造器。
    ConstructorArgumentValues constructorArgumentValues = new ConstructorArgumentValues();
            constructorArgumentValues.addIndexedArgumentValue(0,"abc");
            genericBeanDefinition.setConstructorArgumentValues(constructorArgumentValues);

    这里会调用的是一个参数是字符串的构造方法。

    BeanPostProcessor

     BeanPostProcessor称为后置处理器,spring框架中很多技术实现了此接口。例如自动注入等,spring中使用了5个子类初始化bean。这个以后再说

     

     

     

     此方法中:

     

     

     这里调用的方法就是实例化前和实例化后。

    使用示例:

    @Component
    public class MyBeanPostProcessor implements BeanPostProcessor {
    
        @Override
        public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
            // TODO Auto-generated method stub
            System.out.println("postProcessBeforeInitialization..."+beanName+"=>"+bean);
            return bean;
        }
    
        @Override
        public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
            // TODO Auto-generated method stub
            System.out.println("postProcessAfterInitialization..."+beanName+"=>"+bean);
            return bean;
        }
    
    }
  • 相关阅读:
    ADO.NET入门教程(五) 细说数据库连接池
    Delphi下使用指针的简单总结
    Delphi
    Delphi
    Delphi
    TXLSReadWriteII5 单元格读写
    [Delphi]Delphi开发的一些技巧
    TXLSReadWriteII2版本导出Excel文件:
    Tomcat使用startup启动,一闪而过,如何查看出错信息
    【转】Java保留固定小数位的4种方法
  • 原文地址:https://www.cnblogs.com/SunSAS/p/12295670.html
Copyright © 2011-2022 走看看