Spring其实就是一个管理Bean对象的工厂。它负责对象的创建,对象的销毁等。
所谓的生命周期就是:对象从创建开始到最终销毁的整个过程。
什么时候创建Bean对象?
创建Bean对象的前后会调用什么方法?
Bean对象什么时候销毁?
Bean对象的销毁前后调用什么方法?
Bean
生命周期的管理,可以参考Spring
的源码:AbstractAutowireCapableBeanFactory类的doCreateBean()方法
。
Bean
生命周期可以粗略的划分为五大步:
Bean
Bean
属性赋值Bean
(会调用Bean
的init
方法。注意:这个init
方法需耍自已写,自己配。)Bean
Bean
(会调用Bean
的destroy
方法。注意:这个destroy
方法需耍自已写,自己配。)public class User {
private String name;
public User() {
System.out.println("第一步:无参数构造方法执行");
}
public void setName(String name) {
System.out.println("第二步:给对象的属性赋值");
this.name = name;
}
//需要自己写,自己配
public void initBean() {
System.out.println("第三步:初始化Bean");
}
//需要自己写,自己配
public void destroy() {
System.out.println("第五步:销毁Bean");
}
}
init-method="initBean" destroy-method="destroy"
<bean id="user" class="com.cjf.bean.User" init-method="initBean" destroy-method="destroy">
<property name="name" value="zs"/>
bean>
@Test
public void testBeanLifeCycleFive() {
ApplicationContext applicationContext = new ClassPathXmlApplicationContext("springBean.xml");
User user = applicationContext.getBean("user", User.class);
System.out.println("第四步:使用Bean: " + user);
//注意:必须手动关闭Spring容器,才会销毁Bean
ClassPathXmlApplicationContext context = (ClassPathXmlApplicationContext) applicationContext;
context.close();
}
在以上的5步中,第3步是初始化Bean
,如果你还想在初始化前和初始化后添加代码,可以加入“Bean后处理器”。
编写一个类实现BeanPostProcessor
类,并且重写before
和after
方法:
第一步:实例化Bean
第二步:Bean属性赋值
第三步:执行“Bean后处理器”的before
方法
第四步:初始化Bean(会调用Bean 的init方法。注意:这个init
方法需耍自已写,自己配。)
第五步:执行“Bean后处理器”的after
方法
第六步:使用Bean
第七步:销毁Bean(会调用Bean的destroy 方法。注意:这个destroy
方法需耍自已写,自己配。)
测试类
@Test
public void testBeanLifeCycleFive() {
ApplicationContext applicationContext = new ClassPathXmlApplicationContext("springBean.xml");
User user = applicationContext.getBean("user", User.class);
System.out.println("第六步:使用Bean: " + user);
//注意:必须手动关闭Spring容器,才会销毁Bean
ClassPathXmlApplicationContext context = (ClassPathXmlApplicationContext) applicationContext;
context.close();
}
LogBeanPostProcessor
public class LogBeanPostProcessor implements BeanPostProcessor {
@Override
public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
System.out.println("执行Bean后处理器的before方法");
return BeanPostProcessor.super.postProcessBeforeInitialization(bean, beanName);
}
@Override
public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
System.out.println("执行Bean后处理器的after方法");
return BeanPostProcessor.super.postProcessAfterInitialization(bean, beanName);
}
}
SpringBean.xml
<bean class="com.cjf.bean.LogBeanPostProcessor"/>
<bean id="user" class="com.cjf.bean.User" init-method="initBean" destroy-method="destroy">
<property name="name" value="zs"/>
bean>
源码分析
点位:
在“Bean后处理器”before方法之前
Aware
相关的接口,若实现了则调用这些接口中的方法在“Bean后处理器”before方法之后
InitializingBean
使用Bean之后,或者在销毁
Bean之前
DisposableBean
添加的这三个点位的特点。都是在检查你这个Bean
是否实现了某些特定的接口,如果实现了这些接口,则Spring
容器会调用这个接口中的方法。
如果根据源码跟踪,可以划分更细粒度的步骤,10步:
是否实现了Aware
的相关接口是什么意思?
Aware
相关的接口包括:BeanNameAware
、BeanClassLoaderAware
、BeanFactoryAware
BeanNameAware
,Spring会将Bean的名字
传递给Bean。BeanClassLoaderAware
,Spring会将加载该Bean的类加载器
传递给Bean。BeanFactoryAware
,Spring会将Bean工厂对象
传递给Bean。public class User implements InitializingBean,DisposableBean, BeanNameAware, BeanClassLoaderAware, BeanFactoryAware {
private String name;
public User() {
System.out.println("第一步:无参数构造方法执行");
}
public void setName(String name) {
System.out.println("第二步:给对象的属性赋值");
this.name = name;
}
//需要自己写,自己配
public void initBean() {
System.out.println("第四步:初始化Bean");
}
//需要自己写,自己配
public void myDestroy() {
System.out.println("第七步:销毁Bean");
}
@Override
public void setBeanClassLoader(ClassLoader classLoader) {
System.out.println("Bean这个类的加载器: " + classLoader);
}
@Override
public void setBeanFactory(BeanFactory beanFactory) throws BeansException {
System.out.println("生产Bean的工厂是: " + beanFactory);
}
@Override
public void setBeanName(String s) {
System.out.println("Bean的名字: " + s);
}
@Override
public void afterPropertiesSet() throws Exception {
System.out.println("InitializingBean 的 afterPropertiesSet 方法执行");
}
@Override
public void destroy() throws Exception {
System.out.println("DisposableBean 的 destroy 方法执行");
}
}