Spring bean的生命周期只有四个主要阶段,其他都是在这四个主要阶段前后的扩展点,这四个阶段是: 1.实例化 Instantiation 2.属性赋值 Populate 3.初始化 Initialization 4.销毁 Destruction 其中实例化和属性赋值分别对应构造方法和setter方法的注入,初始化和销毁是用户能自定义扩展的两个阶段。
可通过查源码的方式发现,他们都在doCreate()方法中,
// 忽略了无关代码 protected Object doCreateBean(final String beanName, final RootBeanDefinition mbd, final @Nullable Object[] args) throws BeanCreationException { // Instantiate the bean. BeanWrapper instanceWrapper = null; if (instanceWrapper == null) { // 实例化阶段! instanceWrapper = createBeanInstance(beanName, mbd, args); } // Initialize the bean instance. Object exposedObject = bean; try { // 属性赋值阶段! populateBean(beanName, mbd, instanceWrapper); // 初始化阶段! exposedObject = initializeBean(beanName, exposedObject, mbd); } }可以发现,分别调用三种方法: 1.createBeanInstance() -> 实例化 2.populateBean() -> 属性赋值 3.initializeBean() -> 初始化 而销毁阶段是在容器关闭时调用的,在ConfigurableApplicationContext类的close()中
两个最重要的接口: InstantiationAwareBeanPostProcessor BeanPostProcessor 实现这两个接口的bean,会自动切入到相应的生命周期中,其中InstantiationAwareBeanPostProcessor是作用于实例化阶段的前后,BeanPostProcessor是作用于初始化阶段的前后。 具体代码如图:
package cn.xmx.ioc.lifecycle; import org.springframework.beans.BeansException; import org.springframework.beans.PropertyValues; import org.springframework.beans.factory.config.InstantiationAwareBeanPostProcessorAdapter; import java.beans.PropertyDescriptor; public class MyInstantiationAwareBeanPostProcessorAdapter extends InstantiationAwareBeanPostProcessorAdapter { @Override public Object postProcessBeforeInstantiation(Class<?> beanClass, String beanName) throws BeansException { if(beanName.equals("car")){ System.out.println(beanName+"在实例化之前"); } return super.postProcessBeforeInstantiation(beanClass, beanName); } @Override public boolean postProcessAfterInstantiation(Object bean, String beanName) throws BeansException { if(beanName.equals("car")){ System.out.println(beanName+"在实例化之后"); } return super.postProcessAfterInstantiation(bean, beanName); } } package cn.xmx.ioc.lifecycle; import java.lang.reflect.Proxy; import org.springframework.beans.BeansException; import org.springframework.beans.factory.config.BeanPostProcessor; //后置处理器 public class NdBeanPostProcessor implements BeanPostProcessor { public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException { System.out.println("NdBeanPostProcessor 在"+beanName+"对象初始化之【前】调用......"); if(beanName.equals("car")) { return new CglibInterceptor().getIntance(bean.getClass()); } return bean; } public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException { System.out.println("NdBeanPostProcessor 在"+beanName+"对象初始化之【后】调用......"); return bean; } } package cn.xmx.ioc.lifecycle; import org.springframework.beans.factory.config.BeanPostProcessor; import org.springframework.beans.factory.config.InstantiationAwareBeanPostProcessorAdapter; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; @Configuration public class MainConfig { @Bean(name="car",initMethod="init",destroyMethod="destroy") public Car getCar() { return new Car("大黄蜂"); } @Bean public BeanPostProcessor getBeanPostProcessor() { return new NdBeanPostProcessor(); } @Bean public InstantiationAwareBeanPostProcessorAdapter getIns(){ return new MyInstantiationAwareBeanPostProcessorAdapter(); } } package cn.xmx.ioc.lifecycle; import org.springframework.context.annotation.AnnotationConfigApplicationContext; /* 四个主生命周期 (1)实例化之前干预 InstantiationAwareBeanPostProcessorAdapter.postProcessBeforeInstantiation() 1.实例化 (2)实例化之后干预 InstantiationAwareBeanPostProcessorAdapter.postProcessAfterInstantiation() 2.填充属性(给属性赋值) (1)初始化之前干预 BeanPostProcessor.postProcessBeforeInitialization() 3.初始化化(比如准备资源文件) 3) 属性进行干预 ----修改属性或属性值 (2)初始化之后干预 BeanPostProcessor.postProcessAfterInitialization() 4.销毁(释放资源---对象从内存销毁) N个接口 1、干预多次 1)BeanPostProcessor 2、干预一次 1)Aware */ public class TestLifeCycle { public static void main(String[] args) { AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(MainConfig.class); Car car = (Car) context.getBean("car"); System.out.println(car);//toString System.out.println("beanname:"+car.getBeanName()); System.out.println("beanfactory:"+car.getBeanFactory()); System.out.println("applicationContext:"+car.getApplicationContext()); } }BeanNameAware BeanFactoryAware ApplicationContextAware 需要实体类实现这些接口,分别调用 Bean 的 setBeanName() 方法传入当前 Bean 的 id 值,调用 setBeanFactory() 方法传入当前工厂实例的引用,调用 setApplicationContext() 方法传入当前 ApplicationContext 实例的引用。 具体代码如下图所示:
package cn.xmx.ioc.lifecycle; import org.springframework.beans.BeansException; import org.springframework.beans.factory.BeanFactory; import org.springframework.beans.factory.BeanFactoryAware; import org.springframework.beans.factory.BeanNameAware; import org.springframework.context.ApplicationContext; import org.springframework.context.ApplicationContextAware; public class Car implements BeanNameAware, BeanFactoryAware, ApplicationContextAware { private String name; private String beanName; private BeanFactory beanFactory; private ApplicationContext applicationContext; public void init() { System.out.println("car 在初始化---加载资源"); } public void destroy() { System.out.println("car 在销毁---释放资源"); } public Car() { super(); } public String getName() { return name; } public void setName(String name) { this.name = name; } public Car(String name) { super(); this.name = name; System.out.println("car实例化了"); } public void setBeanFactory(BeanFactory beanFactory) throws BeansException { System.out.println("beanFactory:"+beanFactory); this.beanFactory = beanFactory; } public BeanFactory getBeanFactory(){ return this.beanFactory; } public void setBeanName(String s) { System.out.println("beanName:"+s); this.beanName = s ; } public String getBeanName() { return this.beanName; } public ApplicationContext getApplicationContext() { return this.applicationContext; } public void setApplicationContext(ApplicationContext applicationContext) throws BeansException { System.out.println("applicationContext:"+applicationContext); this.applicationContext = applicationContext; } }实例化和属性赋值都是Spring帮助我们做的,能够自己实现的有初始化和销毁两个生命周期阶段。 1.InitializingBean 对应生命周期的初始化阶段,在源码的invokeInitMethods(beanName, wrappedBean, mbd);方法中调用。 2.DisposableBean 类似于InitializingBean,对应生命周期的销毁阶段,以ConfigurableApplicationContext#close()方法作为入口,实现是通过循环取所有实现了DisposableBean接口的Bean然后调用其destroy()方法 。
Bean 生命周期的整个执行过程描述如下:
如果创建了一个类继承了InstantiationAwareBeanPostProcessorAdapter接口,并在配置文件中配置了该类的注入,即InstantiationAwareBeanPostProcessorAdapter和bean关联,则Spring将调用该接口的postProcessBeforeInstantiation()方法。根据配置情况调用 Bean 构造方法或工厂方法实例化 Bean。如果InstantiationAwareBeanPostProcessorAdapter和bean关联,则Spring将调用该接口的postProcessAfterInstantiation()方法。利用依赖注入完成 Bean 中所有属性值的配置注入。如果 Bean 实现了 BeanNameAware 接口,则 Spring 调用 Bean 的 setBeanName() 方法传入当前 Bean 的 id 值。如果 Bean 实现了 BeanFactoryAware 接口,则 Spring 调用 setBeanFactory() 方法传入当前工厂实例的引用。如果 Bean 实现了 ApplicationContextAware 接口,则 Spring 调用 setApplicationContext() 方法传入当前 ApplicationContext 实例的引用。如果 BeanPostProcessor 和 Bean 关联,则 Spring 将调用该接口的预初始化方法 postProcessBeforeInitialzation() 对 Bean 进行加工操作,此处非常重要,Spring 的 AOP 就是利用它实现的。如果 Bean 实现了 InitializingBean 接口,则 Spring 将调用 afterPropertiesSet() 方法。如果在配置文件中通过 init-method 属性指定了初始化方法,则调用该初始化方法。如果 BeanPostProcessor 和 Bean 关联,则 Spring 将调用该接口的初始化方法 postProcessAfterInitialization()。 注意:以上工作完后才能以后就可以应用这个bean了,那这个bean是一个singleton的,所以一般这种情况下我们调用同一个id的bean会是在内容地址相同的实例,当然在spring配置文件中也可以配置非Singleton。如果 Bean 实现了 DisposableBean 接口,则 Spring 会调用 destory() 方法将 Spring 中的 Bean 销毁;如果在配置文件中通过 destory-method 属性指定了 Bean 的销毁方法,则 Spring 将调用该方法对 Bean 进行销毁。