用了好久的spring,對(duì)bean的生命周期一直 一知半解刻获。今天百度谷歌詳細(xì)了解了下,在此做個(gè)整理绢要。
bean的生命周期
下面是我畫的一個(gè)粗略的流程圖
下面介紹幾個(gè)關(guān)鍵的接口
1. BeanFactoryPostProcessor
這個(gè)接口只有一個(gè)實(shí)現(xiàn)方法,它只有一個(gè)方法postProcessBeanFactory屿衅。
void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException;
spring會(huì)在構(gòu)造完beanFactory后執(zhí)行這個(gè)方法(所有的bean尚未初始化),這時(shí)候如果我們想對(duì)beanFactory進(jìn)行修改,就可以實(shí)現(xiàn)這個(gè)方法九昧。
注意,如果在BeanFactoryPostProcessor中注入其他的bean對(duì)象,這些對(duì)象會(huì)提前初始化,但是初始化前后不會(huì)調(diào)用BeanPostProcessor接口的對(duì)應(yīng)方法
2. BeanPostProcessor
再來看看BeanPostProcessor類,在BeanFactoryPostProcessor 的postProcessBeanFactory被執(zhí)行后,實(shí)現(xiàn)BeanPostProcessor接口的對(duì)應(yīng)類就會(huì)被構(gòu)造了。我們?cè)賮砜纯催@個(gè)接口的兩個(gè)方法:
Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException;
Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException;
方法名寫的很明確了,postProcessBeforeInitialization在bean初始化前會(huì)被調(diào)用,postProcessAfterInitialization在bean初始化后會(huì)被調(diào)用叠蝇。
- 注意,初始化不是調(diào)用構(gòu)造器構(gòu)造類,這里的初始化指的是 bean調(diào)用InitializingBean的初始化方法或者調(diào)用 <init-method>方法來完成初始化璃岳。
所以postProcessBeforeInitialization和postProcessAfterInitialization方法是在這兩個(gè)執(zhí)行前后執(zhí)行的。
BeanPostProcessor的兩個(gè)方法對(duì)所有bean都會(huì)起作用,也就是說,spring容器有幾個(gè)bean,就會(huì)調(diào)用幾次方法
3. InstantiationAwareBeanPostProcessor
這個(gè)接口其實(shí)就是 BeanPostProcessor 的擴(kuò)展悔捶。多增加了bean實(shí)例構(gòu)造前后執(zhí)行的方法,和注入屬性前執(zhí)行的方法铃慷。
它比BeanPostProcessor多了下面這3個(gè)方法。
Object postProcessBeforeInstantiation(Class<?> beanClass, String beanName) throws BeansException;
boolean postProcessAfterInstantiation(Object bean, String beanName) throws BeansException;
PropertyValues postProcessPropertyValues(PropertyValues pvs, PropertyDescriptor[] pds, Object bean, String beanName) throws BeansException;
4. Aware 接口
如果bean 實(shí)現(xiàn)了BeanNameAware,BeanFactoryAware等接口,在注入完屬性后會(huì)調(diào)用相應(yīng)的接口方法蜕该。
比如BeanNameAware的setBeanName方法犁柜。BeanFactoryAware的setBeanFactory方法。
還有一個(gè)ApplicationContextAware接口也會(huì)在后面調(diào)用蛇损。
5. InitializingBean
如果bean實(shí)現(xiàn)了這個(gè)接口,那在bean注入屬性完成后會(huì)執(zhí)行對(duì)應(yīng)的afterPropertiesSet方法赁温。
6. DisposableBean
如果bean實(shí)現(xiàn)這個(gè)接口,那銷毀的時(shí)候就會(huì)執(zhí)行destroy方法坛怪。
下面總結(jié)一下
為了便于記憶淤齐,我們可以把上面的生命周期涉及到的類和接口歸成3大類。
- 針對(duì)bean容器級(jí)別袜匿,也就是BeanFactoryPostProcessor這個(gè)接口更啄,這個(gè)是在bean工廠構(gòu)造后執(zhí)行對(duì)應(yīng)的方法。
- 針對(duì)所有bean級(jí)別居灯,涉及所有bean構(gòu)造前后祭务,初始化前后的操作。也就是BeanPostProcessor和InstantiationAwareBeanPostProcessor接口怪嫌。其中InstantiationAwareBeanPostProcessor其實(shí)也是BeanPostProcessor的一個(gè)子類义锥,BeanPostProcessor本身是在類初始化前后執(zhí)行對(duì)應(yīng)的方法,InstantiationAwareBeanPostProcessor做了一些擴(kuò)展岩灭,可以在類構(gòu)造前后執(zhí)行對(duì)應(yīng)的方法拌倍。
- 最后,只針對(duì)某個(gè)類級(jí)別。BeanNameAware,BeanFactoryAware,ApplicationContextAware, InitializingBean,DisposableBean等接口都是針對(duì)某個(gè)bean的構(gòu)造前后執(zhí)行方法或者初始化前后執(zhí)行方法柱恤。同樣,在xml定義init-method方法或destory-method也是具體到某個(gè)bean数初。我們可以把它們都?xì)w到 Bean級(jí)別的接口方法上面
Bean的生命周期大體就這樣了。有不對(duì)的地方煩請(qǐng)指出!