一、从源码注释看bean生命周期
从JDK源码注释上看,BeanFactory实现类需要支持Bean的完整生命周期,完整的初始化方法及其标准顺序(格式:接口 方法)为:
1.BeanNameAware setBeanName 设置bean名称
2.BeanClassLoaderAware setBeanClassLoader 设置bean类加载器
3.BeanFactoryAware setBeanFactory 设置bean工厂
4.EnvironmentAware setEnvironment 设置环境:profiles+properties
5.EmbeddedValueResolverAware setEmbeddedValueResolver 设置嵌入式值解析器
6.ResourceLoaderAware setResourceLoader 设置资源载入器,只适用于在应用程序上下文中运行
7.ApplicationEventPublisherAware setApplicationEventPublisher注入应用事件发布器ApplicationEventPublisher
8.MessageSourceAware setMessageSource 设置国际化支持
9.ApplicationContextAware setApplicationContext 设置应用上下文
10.ServletContextAware setServletContext 设置servlet上下文
11.BeanPostProcessors postProcessBeforeInitialization 执行bean处理器前置方法
12.InitializingBean afterPropertiesSet 执行初始化Bean设置完属性后置方法
13.a custom init-method definition 执行自定义初始化方法
14.BeanPostProcessors postProcessAfterInitialization 执行bean处理器后置方法
销毁顺序:
1.DestructionAwareBeanPostProcessors postProcessBeforeDestruction 销毁处理器的前置方法
2.DisposableBean destroy Bean销毁回调方法
3.a custom destroy-method definition 用户自定义销毁方法
当然这里面不是所有方法都走一遍,核心方法流程图如下图:
二、测试验证
2.1分析原理
前面说的17个步骤都可以测试,我们选取其中的8个步骤进行测试如下:
初始化流程:
1.BeanNameAware setBeanName 设置bean名称
3.BeanFactoryAware setBeanFactory 设置bean工厂
11.BeanPostProcessors postProcessBeforeInitialization 执行bean处理器前置方法
12.InitializingBean afterPropertiesSet 执行初始化Bean设置完属性后置方法
13.a custom init-method definition 执行自定义初始化方法
14.BeanPostProcessors postProcessAfterInitialization 执行bean处理器后置方法
销毁流程:
2.DisposableBean destroy Bean销毁回调方法
3.a custom destroy-method definition 用户自定义销毁方法
2.2 代码清单
1.构建一个Person类,实现BeanFactoryAware, BeanNameAware, InitializingBean, DisposableBean接口。
1 package spring.ioc; 2 3 import org.springframework.beans.BeansException; 4 import org.springframework.beans.factory.BeanFactory; 5 import org.springframework.beans.factory.BeanFactoryAware; 6 import org.springframework.beans.factory.BeanNameAware; 7 import org.springframework.beans.factory.DisposableBean; 8 import org.springframework.beans.factory.InitializingBean; 9 10 public class Person implements BeanFactoryAware, BeanNameAware, InitializingBean, DisposableBean { 11 12 private String name; 13 14 private String mobile; 15 16 public Person() { 17 super(); 18 System.out.println("[构造器] 调用Person的构造器实例化"); 19 } 20 21 public String getName() { 22 return name; 23 } 24 25 public void setName(String name) { 26 System.out.println("[属性注入] name="+name); 27 this.name = name; 28 } 29 30 public String getMobile() { 31 return mobile; 32 } 33 34 public void setMobile(String mobile) { 35 System.out.println("[属性注入] mobile="+mobile); 36 this.mobile = mobile; 37 } 38 39 @Override 40 public void destroy() throws Exception { 41 System.out.println("[接口DisposableBean.destroy() ]"); 42 } 43 44 @Override 45 public void afterPropertiesSet() throws Exception { 46 System.out.println("[接口InitializingBean.afterPropertiesSet() ]"); 47 } 48 49 @Override 50 public void setBeanName(String name) { 51 System.out.println("[接口BeanNameAware.setBeanName() ]"); 52 } 53 54 @Override 55 public void setBeanFactory(BeanFactory beanFactory) throws BeansException { 56 System.out.println("[接口BeanFactoryAware.setBeanFactory() ]"); 57 } 58 59 public void myInit(){ 60 System.out.println("[init-method]调用<bean>的init-method属性指定的初始化方法"); 61 } 62 63 public void myDestory() { 64 System.out.println("[destroy-method]调用<bean>的destroy-method属性指定的销毁方法"); 65 } 66 67 }
2.自定义工厂后处理器,复写postProcessBeanFactory方法,获取bean定义后添加属性mobile=110
1 package spring.ioc; 2 3 import org.springframework.beans.BeansException; 4 import org.springframework.beans.factory.config.BeanDefinition; 5 import org.springframework.beans.factory.config.BeanFactoryPostProcessor; 6 import org.springframework.beans.factory.config.ConfigurableListableBeanFactory; 7 8 /** 9 * 10 * @ClassName:MyBeanFactoryPostProcessor 11 * @Description:自定义工厂后处理器 12 * @author diandian.zhang 13 * @date 2017年10月25日下午7:14:09 14 */ 15 public class MyBeanFactoryPostProcessor implements BeanFactoryPostProcessor { 16 17 public MyBeanFactoryPostProcessor() { 18 super(); 19 System.out.println("[MyBeanFactoryPostProcessor工厂后处理器]BeanFactoryPostProcessor实现类构造器!!"); 20 } 21 22 @Override 23 public void postProcessBeanFactory(ConfigurableListableBeanFactory arg0) 24 throws BeansException { 25 System.out.println("[MyBeanFactoryPostProcessor工厂后处理器]BeanFactoryPostProcessor.postProcessBeanFactory()获取bean定义后添加属性mobile=110"); 26 BeanDefinition bd = arg0.getBeanDefinition("person"); 27 bd.getPropertyValues().addPropertyValue("mobile", "110"); 28 } 29 30 }
3.自定义Bean后处理器,复写postProcessBeforeInitialization和postProcessAfterInitialization2个方法,分别对应初始化前后时的操作。
1 package spring.ioc; 2 3 import org.springframework.beans.BeansException; 4 import org.springframework.beans.factory.config.BeanPostProcessor; 5 6 /** 7 * 8 * @ClassName:MyBeanPostProcessor 9 * @Description:自定义Bean后处理器 10 * @author diandian.zhang 11 * @date 2017年10月25日下午7:03:53 12 */ 13 public class MyBeanPostProcessor implements BeanPostProcessor { 14 15 public MyBeanPostProcessor() { 16 super(); 17 System.out.println("这是BeanPostProcessor实现类构造器!!"); 18 } 19 20 /** 21 * 22 * @Description 初始化前,处理器 23 * @param bean 24 * @param beanName 25 * @return 26 * @throws BeansException 27 * @author diandian.zhang 28 * @date 2017年10月25日下午7:07:02 29 * @see org.springframework.beans.factory.config.BeanPostProcessor#postProcessBeforeInitialization(java.lang.Object, java.lang.String) 30 */ 31 @Override 32 public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException { 33 System.out.println("BeanPostProcessor接口方法postProcessBeforeInitialization对属性进行更改!beanName="+beanName); 34 return bean; 35 } 36 37 /** 38 * 39 * @Description 初始化后,处理器 40 * @param bean 41 * @param beanName 42 * @return 43 * @throws BeansException 44 * @author diandian.zhang 45 * @date 2017年10月25日下午7:07:07 46 * @see org.springframework.beans.factory.config.BeanPostProcessor#postProcessAfterInitialization(java.lang.Object, java.lang.String) 47 */ 48 @Override 49 public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException { 50 System.out.println("BeanPostProcessor接口方法postProcessAfterInitialization对属性进行更改!beanName="+beanName); 51 return bean;//注意,如果返回null,后续BeanPostProcessor不会再执行 52 } 53 54 55 }
4.自定义实例化bean后处理器适配器,复写postProcessBeforeInstantiation、postProcessBeforeInstantiation、postProcessPropertyValues分别对应实例化Bean前调用、实例化Bean后调用、设置某个属性时调用
注意:InstantiationAwareBeanPostProcessorAdapter ,这里是实例化Instantiation,不是初始化Initialization!!!
1 package spring.ioc; 2 3 import java.beans.PropertyDescriptor; 4 5 import org.springframework.beans.BeansException; 6 import org.springframework.beans.PropertyValues; 7 import org.springframework.beans.factory.config.InstantiationAwareBeanPostProcessorAdapter; 8 9 /** 10 * 11 * @ClassName:MyInstantiationAwareBeanPostProcessor 12 * @Description:BeanPostProcessor的子类,增加了更多自定方法 13 * @author diandian.zhang 14 * @date 2017年10月25日下午7:09:15 15 */ 16 public class MyInstantiationAwareBeanPostProcessor extends 17 InstantiationAwareBeanPostProcessorAdapter { 18 19 public MyInstantiationAwareBeanPostProcessor() { 20 super(); 21 System.out.println("这是InstantiationAwareBeanPostProcessorAdapter实现类构造器!!"); 22 } 23 24 // 接口方法、实例化Bean之前调用 25 @Override 26 public Object postProcessBeforeInstantiation(Class<?> beanClass,String beanName) throws BeansException { 27 System.out.println("InstantiationAwareBeanPostProcessor调用postProcessBeforeInstantiation方法[实例化Bean之前调用 ]beanname="+beanName); 28 return null; 29 } 30 31 // 接口方法、实例化Bean之后调用 32 @Override 33 public Object postProcessAfterInitialization(Object bean, String beanName) 34 throws BeansException { 35 System.out .println("InstantiationAwareBeanPostProcessor调用postProcessAfterInitialization方法[实例化Bean之后调用]beanname="+beanName); 36 return bean; 37 } 38 39 // 接口方法、设置某个属性时调用 40 @Override 41 public PropertyValues postProcessPropertyValues(PropertyValues pvs, 42 PropertyDescriptor[] pds, Object bean, String beanName) 43 throws BeansException { 44 System.out.println("InstantiationAwareBeanPostProcessor调用postProcessPropertyValues方法 pvs="+pvs+",beanName="+beanName); 45 return pvs; 46 } 47 }
5.测试类,使用ClassPathXmlApplicationContext从xml中读取bean配置文件生成applicationContext容器应用上下文,这一步对应容器初始化。第二部从应用上下文中获取bean。最后一步注册一个关闭钩子,在容器关闭时触发。
1 package spring.ioc; 2 3 import org.junit.Test; 6 import org.springframework.context.ApplicationContext; 7 import org.springframework.context.support.ClassPathXmlApplicationContext;10 11 import spring.aop.xml.dao.Dao; 12 13 /** 14 * 15 * @ClassName:IOCTest 16 * @Description:测试类 17 * @author diandian.zhang 18 * @date 2017年10月25日下午4:42:01 19 */ 22 public class IOCTest { 35 36 @Test 37 public void iocPersonTest(){ 38 System.out.println("=============容器初始化======start========="); 39 @SuppressWarnings("resource") 40 ApplicationContext applicationContext = new ClassPathXmlApplicationContext("simple_spring_bean.xml");//源码入口 41 System.out.println("=============容器初始化=======end========"); 42 System.out.println("=============获取person bean====start======="); 43 Person person = applicationContext.getBean("person",Person.class);//获取Bean 44 System.out.println("=============获取person bean====end=======,person类名="+person.getClass().getName()); 45 System.out.println("=============注册关闭钩子,关闭容器(JVM shutdown)时触发钩子!================"); 46 ((ClassPathXmlApplicationContext)applicationContext).registerShutdownHook(); 47 } 48 }
直接运行,结果如下:
=============容器初始化======start========= log4j:WARN No appenders could be found for logger (org.springframework.core.env.StandardEnvironment). log4j:WARN Please initialize the log4j system properly. [MyBeanFactoryPostProcessor工厂后处理器]BeanFactoryPostProcessor实现类构造器!! [MyBeanFactoryPostProcessor工厂后处理器]BeanFactoryPostProcessor.postProcessBeanFactory()获取bean定义后添加属性mobile=110 这是BeanPostProcessor实现类构造器!! 这是InstantiationAwareBeanPostProcessorAdapter实现类构造器!! InstantiationAwareBeanPostProcessor调用postProcessBeforeInstantiation方法[实例化Bean之前调用 ]beanname=person [构造器] 调用Person的构造器实例化 InstantiationAwareBeanPostProcessor调用postProcessPropertyValues方法 pvs=PropertyValues: length=2; bean property 'mobile'; bean property 'name',beanName=person [属性注入] mobile=110 [属性注入] name=张三 [接口BeanNameAware.setBeanName() ] [接口BeanFactoryAware.setBeanFactory() ] BeanPostProcessor接口方法postProcessBeforeInitialization对属性进行更改!beanName=person [接口InitializingBean.afterPropertiesSet() ] [init-method]调用<bean>的init-method属性指定的初始化方法 BeanPostProcessor接口方法postProcessAfterInitialization对属性进行更改!beanName=person InstantiationAwareBeanPostProcessor调用postProcessAfterInitialization方法[实例化Bean之后调用]beanname=person =============容器初始化=======end======== =============获取person bean====start======= =============获取person bean====end=======,person类名=spring.ioc.Person =============注册关闭钩子,关闭容器(JVM shutdown)时触发钩子!================ [接口DisposableBean.destroy() ] [destroy-method]调用<bean>的destroy-method属性指定的销毁方法
总结流程:
====================================
参考
1.JDK8源码
2.全文参考:Spring Bean的生命周期(非常详细),