Spring Bean生命周期学习笔记(1)
Spring作为Java领域最成功的开发框架,是Java程序员工作和面试都绕不过的一道坎,Spring Bean的生命周期更是重中之重。下面先探索一下Bean的生命周期流程,然后再慢慢庖丁解牛深入研究涉及到的相关接口和类。
Spring Bean生命周期流程图
从图中可以看出,Spring Bean的生命周期主要有以下阶段:
- Bean实例化
- Bean属性填充
- 如果该Bean实现了Aware相关接口,则调用相关的方法
- 如果该Bean注册了BeanPostProcessor,则调用BeanPostProcessor的postProcessBeforeInitialization()方法
- 如果该Bean实现了InitializingBean接口,则调用InitializingBean的afterPropertiesSet()方法
- 如果该Bean设置了自定义的init-method方法,则调用自定义的init-method
- 如果该Bean注册了BeanPostProcessor,则调用BeanPostProcessor的postProcessAfterInitialization()方法
- Bean初始化完成,可以使用了
- 容器关闭,如果该bean实现了DisposableBean接口,则调用destroy()方法
- 如果该Bean有自定义的destroy-method方法,则调用指定的destroy-method,至此Bean被销毁。
Spring生命周期详细流程
Spring Bean生命周期方法分类
Bean生命周期中调用了很多方法,根据方法作用范围可将方法大致化分为四类:
方法分类 | 具体方法 |
Bean自身的方法 | Bean的构造方法、属性Set方法以及通过<bean>的init-method和destroy-method所指定的方法 |
Bean级生命周期接口方法 | BeanNameAware、BeanFactoryAware、IntiializingBean和DisposableBean接口的相关方法,这些方法由Bean类直接实现 |
容器级生命周期接口方法 | 有InstantiationAwareBeanPostProcessor和BeanPostProcessor接口,这些后处理器的影响是全局性的 |
工厂后处理器接口方法 | 包括AspectJWeavingEnabler、CustomAutowireConfigurerderer等方法,可用于修改BeanDefinition信息等 |
探究生命周期实例
1、实现所有Bean级生命周期的接口
Person类实现所有Bean级生命周期的接口,并通过init-method和destroy-method指定自定义的初始化方法和销毁方法
public class Person implements InitializingBean, DisposableBean, BeanNameAware, BeanFactoryAware { private String name; private int age; private String gender; private String beanName; private BeanFactory beanFactory; public Person() { System.out.println("我是Person的构造方法"); } // InitializingBean接口方法 @Override public void afterPropertiesSet() throws Exception { System.out.println("InitializingBean接口的afterPropertiesSet方法"); } // DisposableBean接口方法 @Override public void destroy() throws Exception { System.out.println("DisposableBean接口的destroy方法"); } // BeanNameAware接口方法 @Override public void setBeanName(String beanName) { System.out.println("BeanNameAware接口的setBeanName方法"); this.beanName = beanName; } // BeanFactoryAware接口方法 @Override public void setBeanFactory(BeanFactory beanFactory) throws BeansException { System.out.println("BeanFactoryAware接口的setBeanFactory"); this.beanFactory = beanFactory; } public void myInit() { System.out.println("init-method指定自定义初始化方法"); } public void myDestroy() { System.out.println("destroy-method指定自定义销毁方法"); } public String getName() { return name; } public void setName(String name) { System.out.println("设置name属性"); this.name = name; } public int getAge() { return age; } public void setAge(int age) { this.age = age; } public String getGender() { return gender; } public void setGender(String gender) { this.gender = gender; } @Override public String toString() { return "Person{" + "name='" + name + '\'' + ", age=" + age + ", gender='" + gender + '\'' + '}'; } }
2、实现InstantiationAwareBeanPostProcessor接口
MyInstantiationAwareBeanPostProcessor通过继承InstantiationAwareBeanPostProcessor接口的实现类InstantiationAwareBeanPostProcessorAdapter来实现InstantiationAwareBeanPostProcessor接口
public class MyInstantiationAwareBeanPostProcessor extends InstantiationAwareBeanPostProcessorAdapter { public MyInstantiationAwareBeanPostProcessor() { System.out.println("MyInstantiationAwareBeanPostProcessor的构造方法"); } // 实例化Bean前进行调用 @Override public Object postProcessBeforeInstantiation(Class<?> beanClass, String beanName) throws BeansException { System.out.println("InstantiationAwareBeanPostProcessor的postProcessBeforeInstantiation方法"); return null; } // 实例化Bean后进行调用 @Override public boolean postProcessAfterInstantiation(Object bean, String beanName) throws BeansException { System.out.println("InstantiationAwareBeanPostProcessor的postProcessAfterInstantiation方法"); return super.postProcessAfterInstantiation(bean, beanName); } // 设置某个属性时调用 @Override public PropertyValues postProcessPropertyValues(PropertyValues pvs, PropertyDescriptor[] pds, Object bean, String beanName) throws BeansException { System.out.println("InstantiationAwareBeanPostProcessor的postProcessPropertyValues方法"); return pvs; } }
3、实现BeanPostProcessor接口
public class MyBeanPostProcessor implements BeanPostProcessor { public MyBeanPostProcessor() { System.out.println("MyBeanPostProcessor的构造方法"); } @Override public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException { System.out.println("MyBeanPostProcessor的postProcessBeforeInitialization方法"); return bean; } @Override public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException { System.out.println("MyBeanPostProcessor的postProcessAfterInitialization方法"); return bean; } }
4、实现BeanFactoryPostProcessor接口
public class MyBeanFactoryPostProcessor implements BeanFactoryPostProcessor { @Override public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException { System.out.println("调用BeanFactoryPostProcessor接口的postProcessBeanFactory方法"); BeanDefinition beanDefinition = beanFactory.getBeanDefinition("person"); beanDefinition.getPropertyValues().addPropertyValue("age", "21"); } }
5、Xml配置文件
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.2.xsd"> <!--配置Bean的后置处理器--> <bean id="beanPostProcessor" class="com.stduy.MyBeanPostProcessor"> </bean> <!--配置instantiationAwareBeanPostProcessor--> <bean id="instantiationAwareBeanPostProcessor" class="com.stduy.MyInstantiationAwareBeanPostProcessor"> </bean> <!--配置BeanFactory的后置处理器--> <bean id="beanFactoryPostProcessor" class="com.stduy.MyBeanFactoryPostProcessor"> </bean> <bean id="person" class="com.stduy.Person" init-method="myInit" destroy-method="myDestroy"> <property name="name" value="lufei"></property> <property name="age" value="19"></property> <property name="gender" value="man"></property> </bean> </beans>
6、启动类
public class Client { public static void main(String[] args) { ApplicationContext context = new ClassPathXmlApplicationContext("/beans.xml"); System.out.println("-------------------【容器初始化成功】------------------"); Person person = context.getBean("person", Person.class); System.out.println(person); // 关闭容器 ((ClassPathXmlApplicationContext)context).registerShutdownHook(); } }
7、输出结果
调用BeanFactoryPostProcessor接口的postProcessBeanFactory方法
MyBeanPostProcessor的构造方法
MyInstantiationAwareBeanPostProcessor的构造方法
InstantiationAwareBeanPostProcessor的postProcessBeforeInstantiation方法
我是Person的构造方法
InstantiationAwareBeanPostProcessor的postProcessAfterInstantiation方法
InstantiationAwareBeanPostProcessor的postProcessPropertyValues方法
设置name属性
BeanNameAware接口的setBeanName方法
BeanFactoryAware接口的setBeanFactory
MyBeanPostProcessor的postProcessBeforeInitialization方法
InitializingBean接口的afterPropertiesSet方法
init-method指定自定义初始化方法
MyBeanPostProcessor的postProcessAfterInitialization方法
-------------------【容器初始化成功】------------------
Person{name='lufei', age=21, gender='man'}
DisposableBean接口的destroy方法
destroy-method指定自定义销毁方法
通过Spring Bean生命周期流程图和代码实例对Spring Bean生命周期有了初步的了解, 后面逐步深入对Spring Bean生命周期中的各个阶段。