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

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM