由於本人能力有限不能深入源碼講解,這裏知識粗略的介紹一下bean的生命週期,先看一下圖:
用簡單的話來說就是:
-
第一步:通過構造器創建
bean
實例,默認是無參構造器 -
第二步:設置bean的屬性值和引入其他的bean(spring的循環依賴),如果Bean實現了BeanNameAware接口,工廠調用Bean的setBeanName()方法傳遞Bean的ID),如果Bean實現了BeanFactoryAware接口,工廠調用setBeanFactory()方法傳入工廠自身,由於我們是通過
@value
方式賦值,所以第二步直接跳過了 -
第三步:執行初始化方法,如果對象實現了
BeanPostProcessor
接口,通過這個後置處理器實現public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException { System.out.println("初始化方法執行前執行"); return bean; } public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException { System.out.println("初始化方法執行後執行"); return bean; }
這兩個方法,就會在初始化之前/之後分別調用
-
第四步:獲取bean實例
-
第五步:執行銷燬方法
下面我們通過一個例子來具體看一下這個過程:
測試的實體類:
@Component
public class person implements BeanPostProcessor,DisposableBean, InitializingBean {
@Value("威猛先生")
private String name;
public person() {
System.out.println("第一步,調用默認構造器");
}
public person(String name) {
this.name = name;
System.out.println("第一步,調用有參構造器");
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
// @PostConstruct
// public void initMethod(){
// System.out.println("第三步,調用初始化方法");
// }
//
// @PreDestroy
// public void destroyMethod(){
// System.out.println("第五步,執行銷燬的方法");
// }
public void destroy() throws Exception {
System.out.println("第五步,執行銷燬的方法");
}
public void afterPropertiesSet() throws Exception {
System.out.println("第三步,調用初始化方法");
}
public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
System.out.println("初始化方法執行前執行");
return bean;
}
public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
System.out.println("初始化方法執行後執行");
return bean;
}
}
項目結構圖:
main方法:
ApplicationContext ac = new AnnotationConfigApplicationContext(springConfig.class);
person p = (person) ac.getBean("person");
System.out.println("第四步,獲取bean實例");
((AnnotationConfigApplicationContext)ac).close();
看輸出結果:
第一步,調用默認構造器
初始化方法執行前執行
第三步,調用初始化方法
初始化方法執行後執行
第四步,獲取bean實例
第五步,執行銷燬的方法
結果和我們想的一樣,這裏需要提一點:通過實現這兩個DisposableBean, InitializingBean
接口來創建初始化方法和銷燬方法是一種方式,但是通過註解更簡單,也就是剛纔實體類中註釋的部分:
// @PostConstruct
// public void initMethod(){
// System.out.println("第三步,調用初始化方法");
// }
//
// @PreDestroy
// public void destroyMethod(){
// System.out.println("第五步,執行銷燬的方法");
// }
總結:
Bean的完整生命週期經歷了各種方法調用,這些方法可以劃分爲以下幾類:
-
1、Bean自身的方法:這個包括了Bean本身調用的方法和通過配置文件中的init-method和destroy-method指定的方法
-
2、Bean級生命週期接口方法:這個包括了BeanNameAware、BeanFactoryAware、InitializingBean和DiposableBean這些接口的方法
-
3、容器級生命週期接口方法:這個包括了InstantiationAwareBeanPostProcessor 和 BeanPostProcessor 這兩個接口實現,一般稱它們的實現類爲“後處理器”。
-
4、工廠後處理器接口方法:這個包括了AspectJWeavingEnabler, ConfigurationClassPostProcessor, CustomAutowireConfigurer等等非常有用的工廠後處理器 接口的方法。工廠後處理器也是容器級的。在應用上下文裝配配置文件之後立即調用
當我們的應用上下文被加載了,這時候bean容器也隨之加載,bean也被創建(ApplicationContext方式),在容器銷燬前bean都會一直存在容器中,直到該上下文容器被銷燬,bean生命週期也就隨之結束了