时隔一年多,在掌握了Spring、SpringBoot、SpringCloud之后
我再次回头,重新学习Spring框架
Bean的生命周期学习:
在传统的XML配置中,可以这样自定义初始化和销毁方法:
init-method="" destroy-method=""
注解方式的简单使用:
@Configuration public class LifeCircleConfig { @Bean(initMethod = "init",destroyMethod = "destroy") public Car car(){ return new Car(); } }
public class Car { public Car(){ System.out.println("Construct Car!"); } public void init(){ System.out.println("Car init!"); } public void destroy(){ System.out.println("Car destroy!"); } }
public class LifeCircleTest { private static AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext(LifeCircleConfig.class); @Test public void test(){ applicationContext.close(); } }
注意:要有close方法,否则不会打印Car销毁方法
打印如下:
Construct Car! Car init! Car destroy!
这里默认的是单实例Bean
如果是多实例的话,按照以上的测试代码是不会打印的,因为多实例情况下,在获取Bean的情况下才会创建对象
而且在多例情况下,只会调用初始化和构造方法,不会调用销毁方法
以上测试代码只完成了初始化IOC容器,所以什么都不打印
实现Spring中接口方式:这时候不需要在@Bean中进行配置
public class Car implements InitializingBean, DisposableBean { public Car() { System.out.println("Construct Car!"); } public void afterPropertiesSet() throws Exception { System.out.println("Car init!"); } public void destroy() { System.out.println("Car destroy!"); } }
使用Java原生注解:
public class Car { public Car() { System.out.println("Construct Car!"); } @PostConstruct public void init() { System.out.println("Car init!"); } @PreDestroy public void destroy() { System.out.println("Car destroy!"); } }
使用Spring中Bean的后置处理器:
@Component public class MyBeanPostProcessor implements BeanPostProcessor { /** * 初始化前调用 */ public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException { System.out.println("postProcessBeforeInitialization " + bean + " " + beanName); return bean; } /** * 初始化后调用 */ public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException { System.out.println("postProcessAfterInitialization " + bean + " " + beanName); return bean; } }
@Configuration @ComponentScan("org.dreamtech.bean") public class LifeCircleConfig { @Bean public Car car(){ return new Car(); } }
测试后部分打印如下:
Construct Car! postProcessBeforeInitialization [email protected] car postProcessAfterInitialization [email protected] car
BeanPostProcessor原理:
查看这一段源码:
initializeBean(beanName, exposedObject, mbd)方法中:
Object wrappedBean = bean; if (mbd == null || !mbd.isSynthetic()) { wrappedBean = applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName); } try { invokeInitMethods(beanName, wrappedBean, mbd); } catch (Throwable ex) { throw new BeanCreationException( (mbd != null ? mbd.getResourceDescription() : null), beanName, "Invocation of init method failed", ex); } if (mbd == null || !mbd.isSynthetic()) { wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName); }
在invokeInitMethods初始化方法之前
调用了applyBeanPostProcessorsBeforeInitialization,也就是调用了所有PostProcessor的Before方法
在invokeInitMethods初始化方法之后
调用了applyBeanPostProcessorsAfterInitialization,也就是调用了所有PostProcessor的After方法
进入applyBeanPostProcessorsBeforeInitialization方法查看源码:
遍历所有的Processor,一旦返回null,就会跳出循环
@Override public Object applyBeanPostProcessorsBeforeInitialization(Object existingBean, String beanName) throws BeansException { Object result = existingBean; for (BeanPostProcessor beanProcessor : getBeanPostProcessors()) { result = beanProcessor.postProcessBeforeInitialization(result, beanName); if (result == null) { return result; } } return result; }
在initializeBean方法之前,调用的是populateBean方法
作用:给属性赋值
// Initialize the bean instance. Object exposedObject = bean; try { populateBean(beanName, mbd, instanceWrapper); if (exposedObject != null) { exposedObject = initializeBean(beanName, exposedObject, mbd); } }
所以:BeanPostProcessor是在Bean赋值之后,初始化的过程前后执行的
BeanPostProcessor在Spring底层的使用:
获取IOC容器的接口:
public interface ApplicationContextAware extends Aware { void setApplicationContext(ApplicationContext var1) throws BeansException; }
而它就是基于BeanPostProcessor的,代码过长就不截取了
class ApplicationContextAwareProcessor implements BeanPostProcessor
或者是参数校验:也使用到了BeanPostProcessor
public class BeanValidationPostProcessor implements BeanPostProcessor, InitializingBean
部分代码如下:
public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException { if (!this.afterInitialization) { this.doValidate(bean); } return bean; } public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException { if (this.afterInitialization) { this.doValidate(bean); } return bean; }
原文地址:https://www.cnblogs.com/xuyiqing/p/11307820.html