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