Bean的生命周期
相比于我們自己創(chuàng)建的bean的生命周期(通過new關(guān)鍵字實(shí)例化,不再使用了就被回收),Spring容器中bean的生命周期是比較復(fù)雜的。先看看下面Bean生命周期的圖。
圖片來源于網(wǎng)絡(luò)
bean生命周期(來源網(wǎng)絡(luò))
對于上面的圖補(bǔ)充一點(diǎn),在
BeaFactoryAware's setBeanFactory()
和Pre-initialization BeanPostProcessor
之間還應(yīng)該有一步:調(diào)用ApplicationContextAware
的setApplicationContext()
方法。可以看到Bean生命周期要經(jīng)歷很多階段,但這些階段大部分都是可選的。例如,某個(gè)Bean如果實(shí)現(xiàn)了BeanFactoryAware接口的setBeanFactory方法,那么該Bean的生命就會經(jīng)歷這個(gè)階段,如果不實(shí)現(xiàn)則沒有。
下面來看看一個(gè)經(jīng)歷上面全部生命周期階段的bean如何實(shí)現(xiàn)。首先定義Bean對象同時(shí)實(shí)現(xiàn)下列接口BeanNameAware
,BeanFactoryAware
,ApplicationContextAware
,InitializingBean
,DisposableBean
@Component
public class Car implements BeanNameAware,BeanFactoryAware,ApplicationContextAware,
InitializingBean,DisposableBean {
//Seat也是一個(gè)簡單的bean對象
private Seat seat;
public Car(){
System.out.println("car instance...");
}
public Seat getSeat() {
return seat;
}
@Autowired
public void setSeat(Seat seat) {
System.out.println("填充屬性");
this.seat = seat;
}
/**
* 自定義的初始化方法
*/
public void init(){
System.out.println("car ... init...");
}
/**
* 自定義的銷毀方法
*/
public void detory(){
System.out.println("car ... detory...");
}
@Override
public void setBeanName(String s) {
System.out.println(s);
System.out.println("BeanNameAware...setBeanName()");
}
@Override
public void setBeanFactory(BeanFactory beanFactory) throws BeansException {
System.out.println("DisposableBean...setBeanFactory()");
}
@Override
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
System.out.println("ApplicationContextAware...setApplicationContext()");
}
@Override
public void afterPropertiesSet() throws Exception {
System.out.println("InitializingBean...afterPropertiesSet()");
}
@Override
public void destroy() throws Exception {
System.out.println("InitializingBean...destroy()");
}
}
有了自定義初始化方法和銷毀方法之后,還需要對其進(jìn)行配置一下,可以在配置器類中通過@Bean(initMethod="init",destroyMethod="detory")
來指定,或者直接在方法上添加@PostConstruct
或者@PreDestroy
注解。
//對象創(chuàng)建并賦值之后調(diào)用
@PostConstruct
public void init(){
System.out.println("car....@PostConstruct...");
}
//容器移除對象之前
@PreDestroy
public void detory(){
System.out.println("car....@PreDestroy...");
}
然后再定義一個(gè)Bean的后置處理器(BeanPostProcessor
)。
@Component
public class MyBeanPostProcessor implements BeanPostProcessor {
@Override
public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
System.out.println("postProcessBeforeInitialization..."+beanName+"..."+bean);
return bean;
}
@Override
public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
System.out.println("postProcessAfterInitialization..."+beanName+"..."+bean);
return bean;
}
}
最后寫個(gè)測試類,觀察運(yùn)行結(jié)果
@Test
public void test(){
//1、創(chuàng)建ioc容器
AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext(MainConfigOfLifeCycle.class);
System.out.println("容器創(chuàng)建完成...");
applicationContext.getBean("car");
//關(guān)閉容器
applicationContext.close();
}
輸出結(jié)果為:
car instance...
填充屬性
BeanNameAware...setBeanName()
DisposableBean...setBeanFactory()
ApplicationContextAware...setApplicationContext()
postProcessBeforeInitialization...car...cn.zgc.spring.annotation.beans.Car@22b49166
InitializingBean...afterPropertiesSet()
car ... init...
postProcessAfterInitialization...car...cn.zgc.spring.annotation.beans.Car@22b49166
容器創(chuàng)建完成...
InitializingBean...destroy()
car ... detory...
查看輸出結(jié)果可以看到,Car的生命周期和上面的圖吻合。
生命周期構(gòu)建原理
要探究原理就必須得看看Spring源碼中是如何實(shí)現(xiàn)的,我們在自定義的Bean后置處理器MyBeanPostProcessor中打個(gè)斷點(diǎn),跟一下源碼。先來看看方法調(diào)用棧
Bean構(gòu)建方法調(diào)用棧
Spring的源碼是很繁瑣的,很容易讓人陷入細(xì)節(jié)中出不來,因此我們要抓住重點(diǎn)代碼梳理出整體脈絡(luò),而不應(yīng)該過分扣細(xì)節(jié)。這里我們主要來看看
AbstractAutowireCapableBeanFactory
的doCreateBean
方法,在該方法中有這么一段代碼
//對bean進(jìn)行實(shí)例化
if (mbd.isSingleton()) {
instanceWrapper = (BeanWrapper)this.factoryBeanInstanceCache.remove(beanName);
}
if (instanceWrapper == null) {
instanceWrapper = this.createBeanInstance(beanName, mbd, args);
}
......
try {
// 對bean的屬性進(jìn)行填充
this.populateBean(beanName, mbd, instanceWrapper);
if (exposedObject != null) {
exposedObject = this.initializeBean(beanName, exposedObject, mbd);
}
}
繼續(xù)看看initializeBean
方法中都做了些什么
//回調(diào)實(shí)現(xiàn)了xxxAware接口中的方法
this.invokeAwareMethods(beanName, bean);
......
//調(diào)用BeanPostProcessor的postProcessorsBeforeInitialization方法
wrappedBean = this.applyBeanPostProcessorsBeforeInitialization(bean, beanName);
......
try {
//調(diào)用初始化方法(自定義的初始化方法或者實(shí)現(xiàn)InitialzingBean接口)
invokeInitMethods(beanName, wrappedBean, mbd);
}catch (Throwable ex) {
....
}
if (mbd == null || !mbd.isSynthetic()) {
//調(diào)用BeanPostProcessor的postProcessorsAfterInitialization方法
wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);
}
下面我們再結(jié)合源碼,用偽代碼的形式給出Bean的生命周期過程(不包括兩個(gè)銷毀階段)
new Bean();
populateBean(beanName, mbd, instanceWrapper);給bean進(jìn)行屬性賦值
initializeBean() {
applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName);
invokeInitMethods(beanName, wrappedBean, mbd);執(zhí)行自定義初始化
{
if(bean instanceof InitializingBean){
((InitializingBean) bean).afterPropertiesSet();
}
if(mbd.getInitMethodName()!=null){ //自定義初始化方法執(zhí)行
invokeCustomInitMethod(beanName, bean, mbd);
}
}
applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);
}