• Springboot bean加载机制及后置处理器


    /**
     * @author guchuang
     * @DESC 1.本实例的构造函数, 实例化对象(实例化走的是普通java对象实例化的流程),
     *   此时全局变量(注入的服务为空),service服务实例化之后(完成构造函数调用)便可以注入到其它服务之中
     * 2.注入添加了@Autowired注解的服务(即设置实例变量的值)
     * 3.调用BeanNameAware.setBeanName(), 设置bean的名字,名字由注册服务时指定(本实例为a1),不指定的话默认为类名的首字母小写
     * 4.ApplicationContextAware.setApplicationContext(), 设置bean实例运行的上下文ApplicationContext
     * 5.调用@PostConstruct注解的方法, 此时已经完成了依赖注入
     * 6.InitializingBean.afterPropertiesSet(), bean的属性全部设置完毕后调用
     * 7.BeanPostProcessor.postProcessBeforeInitialization() & BeanPostProcessor.postProcessAfterInitialization(), 后置处理器,会被多次调用,每个服务实例都被被调用一次
     *   postProcessBeforeInitialization() 在@PostConstruct之前调用
     *   postProcessAfterInitialization()  在@PostConstruct之后调用
     */
    @Service
    public class TestA implements BeanNameAware, BeanFactoryAware, ApplicationContextAware, InitializingBean, BeanPostProcessor {
        private int order = 1;
    
        @Autowired
        private TestB testB;
    
    
        public TestA() {
            job();
            MyLog.info("Constructor TestA");
            MyLog.sleep(100);
        }
    
        @Override
        public void setBeanName(String name) {
            MyLog.info("BeanNameAware setBeanName, name:" + name);
        }
    
    
        @Override
        public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
            MyLog.info("ApplicationContextAware setApplicationContext, applicationContext:" + applicationContext);
        }
    
        /**
         * 依赖注入完成后调用的方法(此时@Autowired的服务全部已经初始化),即使没有外部依赖,该方法也需要被调用一次
         */
        @PostConstruct
        public void postConstruct() {
            MyLog.info("PostConstruct TestA" + " ,testB is null? " + (testB == null));
        }
    
        @Override
        public void afterPropertiesSet() throws Exception {
            MyLog.info("InitializingBean afterPropertiesSet");
        }
    
        @Override
        public void setBeanFactory(BeanFactory beanFactory) throws BeansException {
            MyLog.info("BeanFactory setBeanFactory");
            //MyLog.info("BeanFactory setBeanFactory, beanFactory:" + beanFactory);
        }
        /*@Override
        public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
            print("BeanFactoryPostProcessor postProcessBeanFactory, beanFactory:" + beanFactory);
        }*/
    
        @Override
        public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
            if (beanName.contains("123")) {
                MyLog.info("BeanPostProcessor postProcessBeforeInitialization, bean:" + bean + ", beanName:" + beanName);
            }
            return BeanPostProcessor.super.postProcessBeforeInitialization(bean, beanName);
        }
    
        @Override
        public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
            if (beanName.contains("123")) {
                MyLog.info("BeanPostProcessor postProcessAfterInitialization, bean:" + bean + ", beanName:" + beanName);
            }
            return BeanPostProcessor.super.postProcessAfterInitialization(bean, beanName);
        }
        
        /*public void print(Object o) {
            MyLog.info(order++ + "." + o + "==========================================");
            MyLog.info(testB != null);
        }*/
    
        public void job() {
            new Thread(() -> {
                MyLog.info("async run1,result: " + (testB != null));
    
                MyLog.sleep(4000);
                MyLog.info("async run2,result: " + (testB != null));
    
            }).start();
        }
    }
    @Service
    public class TestB {
        @Autowired
        TestA a;
    
        public TestB() {
            MyLog.info("Constructor TestB");
            MyLog.sleep(100);
        }
    
        @PostConstruct
        public void postConstruct() {
            MyLog.info("PostConstruct TestB" + " ,a is null? " + (a == null));
        }
    
        public String foo() {
            return "hello world, i am b";
        }
    
    }

    bean的后置处理器

    @Service
    public class TestBean implements BeanNameAware, BeanFactoryAware, ApplicationContextAware, InitializingBean {
    
        @Value("${server.port}")
        String port;
    
        @Autowired
        Tmp1 tmp1;
    
        TestBean() {
            MyLog.info("Constructor TestBean");
        }
    
        @PostConstruct
        public void init() {
            MyLog.info("PostConstructor TestBean, port:" + port);
        }
    
        @Override
        public void setBeanName(String name) {
            MyLog.info("BeanNameAware setBeanName, name:" + name);
        }
    
    
        @Override
        public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
            MyLog.info("ApplicationContextAware setApplicationContext, applicationContext:" + applicationContext);
        }
    
        @Override
        public void afterPropertiesSet() {
            MyLog.info("InitializingBean afterPropertiesSet, port:" + port);
        }
    
        @Override
        public void setBeanFactory(BeanFactory beanFactory) throws BeansException {
            MyLog.info("BeanFactory setBeanFactory");
            //MyLog.info("BeanFactory setBeanFactory, beanFactory:" + beanFactory);
        }
    
    }
    /**
     * @description: bean工厂后置处理器,spring读取完bean定义后,在后续处理之前调用一次,给予修改bean信息的机会
     * @author: guchuang
     * @create: 2019-10-11 08:55
     **/
    @Service
    public class TestBeanFactoryPostProcessor implements BeanFactoryPostProcessor {
    
        /**
         * 这个方法只会被调用一次
         * 所有的bean definition已经加载完成,尚未初始化,这里可以修改bean的定义
         * bean definition包含bean对象的所有信息(接口,继承,属性,方法,注解...)
         * @param beanFactory
         * @throws BeansException
         */
        @Override
        public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
            //MyLog.debug(beanFactory.getBean(TestBean.class));
            MyLog.info("postProcessBeanFactory");
        }
    }
    /**
     * @description: bean对象后置处理器,在bean初始化后期过程中调用
     * bean的生命周期:
     *  1.实例化(调用构造函数生成对象)
     *  2.初始化(注入属性、设置beanName、设置beanFactory、设置applicationContext、调用@PostConstructor方法,调用afterpropertiesSet方法)
     *      BeanPostProcessor作用于: 调用@PostConstructor方法,调用afterpropertiesSet方法前后
     *      调用完postProcessAfterInitialization表示bean已经完全初始化,可以放在bean工厂且能正常使用
     * @author: guchuang
     * @create: 2019-10-09 10:07
     **/
    @Component
    public class TestBeanPostProcessor implements BeanPostProcessor {
    
        public TestBeanPostProcessor() {
            MyLog.info("Constructor TestPostProcessor");
        }
    
        @Override
        public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
            if (beanName.contains("test")) {
                MyLog.info("BeanPostProcessor postProcessBeforeInitialization, bean:" + bean + ", beanName:" + beanName);
            }
            return BeanPostProcessor.super.postProcessBeforeInitialization(bean, beanName);
        }
    
        @Override
        public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
            if (beanName.contains("test")) {
                MyLog.info("BeanPostProcessor postProcessAfterInitialization, bean:" + bean + ", beanName:" + beanName);
            }
            return BeanPostProcessor.super.postProcessAfterInitialization(bean, beanName);
        }
    }
    /**
     * @description: bean实例化(类似new Object())后置处理器,在调用构造函数先后(紧挨着)分别调用这里的两个方法
     * @author: guchuang
     * @create: 2019-10-10 09:31
     **/
    @Component
    public class TestInstantiationAwareBeanPostProcessor implements InstantiationAwareBeanPostProcessor {
    
        @Override
        public Object postProcessBeforeInstantiation(Class<?> beanClass, String beanName) throws BeansException {
            if (beanName.contains("test")) {
                MyLog.info("postProcessBeforeInstantiation, bean:" + beanClass + ", beanName:" + beanName);
            }
            return null;
        }
    
        @Override
        public boolean postProcessAfterInstantiation(Object bean, String beanName) throws BeansException {
            if (beanName.contains("test")) {
                MyLog.info("postProcessBeforeInstantiation, bean:" + bean + ", beanName:" + beanName);
            }
            return true;
        }
    
        @Override
        public PropertyValues postProcessPropertyValues(PropertyValues pvs, PropertyDescriptor[] pds, Object bean, String beanName) throws BeansException {
            if (beanName.contains("test")) {
                MyLog.info("postProcessPropertyValues, bean:" + bean + ", beanName:" + beanName + ", pvs:" + pvs);
            }
            return pvs;
        }
    }
  • 相关阅读:
    中国的人生路上是紧跟领导就会有回报
    重游三峡广场有感
    假如你没有我
    关于中小型软件企业技术管理的建议(转)
    街客
    游歌乐山有感
    高成就者的反常思维
    漫谈创业和管理-程序员5大思维障碍 (转)
    QQ情缘
    javascript library
  • 原文地址:https://www.cnblogs.com/gc65/p/12848579.html
Copyright © 2020-2023  润新知