/** * @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; } }