Spring_IOC_03——Bean的生命周期

此文主要講了Spring中,Bean的生命周期,初始化動(dòng)作,銷毀動(dòng)作是如何執(zhí)行。

以及關(guān)系生命周期各個(gè)接口的作用和自定義實(shí)現(xiàn), 自定義生命周期中執(zhí)行邏輯的一些使用方式。

比如BeanPostProcessor InitializingBean DisposabbleBean 接口的使用 @postConstruct @PreDestroy 標(biāo)簽的使用 以及對(duì)應(yīng)法法的執(zhí)行順序。

對(duì)Spring IOC不了解的,可以參考之前兩篇文章:
Spring_IOC_01——概念講解
Spring_IOC_02——原理解析

Spring Bean的生命周期

先通過一個(gè)流程圖,對(duì)Spring Bean 的生命周期有一個(gè)整體的了解。

Bean生命周期圖解


概述

一個(gè)對(duì)象的生命周期有:創(chuàng)建(初始化-實(shí)例化),使用 和 銷毀。Spring中的Bean也遵循這一原則,但是Spring提供了一些對(duì)外接口,允許開發(fā)者在這三個(gè)過程中做一些額外的操作。

注意 實(shí)例化初始化 的區(qū)別:
在Spring中,實(shí)例化,是為Bean對(duì)象開辟內(nèi)存空間(可以理解為構(gòu)造方法的調(diào)用),初始化,則是對(duì)屬性的初始化,也可以理解為對(duì)屬性的注入(構(gòu)造函數(shù)也有屬性初始化語句,但不屬于這部分)
屬性的注入,是通過setter方法/參數(shù) 注入。不管是通過注解還是XML配置。



相關(guān)接口,方法說明

1) Bean自身的方法:init-method / destory-method , 通過在配置文件bean定義的相應(yīng)屬性中,指定相應(yīng)的執(zhí)行方法。

2)Bean級(jí)別生命周期接口:BeanNameAware,BeanFactoryAware,IntializaingBean,DiposableBean 這些接口的方法。每個(gè)Bean都可以選擇實(shí)現(xiàn),可以選擇各自的自定義操作。

3)容器級(jí)生命周期接口方法:BeanPostProcessor 和 InstantiationAwareBeanPostProcessor(繼承自BeanPostProcessor) 這兩個(gè)的接口的實(shí)現(xiàn)。我們一般稱之為后置處理器,這個(gè)在第二篇文章有講到。這些接口的實(shí)現(xiàn)注冊(cè)到bean的配置文件中,是每個(gè)Bean實(shí)例化或者初始化時(shí)候都會(huì)調(diào)用。

4)工廠后處理器接口方法:這些方法也是容器級(jí)別的。但是它們是在上下文裝置配置文件之后調(diào)用。例如:BeanFactoryPostProcessor,CustomAutowireConfigure等。



Bean 具體生命更周期

初始化過程

1) BeanFactoryPostProcessor.postProcessBeanFactory
工廠后處理器(這名字其實(shí)只是一個(gè)翻譯,意義有時(shí)候并不一定正確),這個(gè)方法其實(shí)和Bean的生命周期沒多少關(guān)系,是 Spring IoC 容器(ApplicationContext)初始化的一部分,詳細(xì)可以參考 IoC 容器初始化的內(nèi)容。

具體是每一次刷新時(shí)(初始化)調(diào)用,它是對(duì) BeanDefinition 進(jìn)行后處理(BeanDefinition可以參考:SpringIoC容器結(jié)構(gòu)),作用是可以修改配置文件的各個(gè) bean 的配置。
實(shí)現(xiàn):寫一個(gè)類實(shí)現(xiàn) BeanFactoryPostProcessor 接口,重寫該方法,并在Spring配置文件中配置這個(gè)類的bean。

2)InstantiationAwareBeanPostProcessor.postProcessBeforeInstantiation
所有bean對(duì)象實(shí)例化之前執(zhí)行,具體就是:執(zhí)行每個(gè)bean類的構(gòu)造函數(shù)之前。
實(shí)現(xiàn):寫一個(gè)類實(shí)現(xiàn) InstantiationAwareBeanPostProcessor 接口,重寫該方法,該方法返回一個(gè)Object,但實(shí)際上返回一個(gè)null即可。在Spring配置文件中配置一個(gè)該類的bean。

3)調(diào)用Bean的構(gòu)造函數(shù),實(shí)例化bean

4)InstantiationAwareBeanPostProcessor.postProcessAfterInstantiation
bean類調(diào)用構(gòu)造函數(shù)實(shí)例化之后,初始化之前,調(diào)用。
實(shí)現(xiàn)同第二步,重寫該方法。注意:這個(gè)返回值是boolean,默認(rèn)為false。要改為true,否則無法注入屬性

5)InstantiationAwareBeanPostProcessor.postProcessPropertyValue
屬性注入之前調(diào)用該方法。
實(shí)現(xiàn)同第二步,注意返回類型是PropertyValues,默認(rèn)返回null,這里需要改為返回第一個(gè)參數(shù)propertyValues。

6)BeanNameAware.setBeanName
屬性注入后調(diào)用,該方法作用是讓bean的類知道自己所在的Bean的name或者id屬性
實(shí)現(xiàn):bean類實(shí)現(xiàn)BeanNameAware接口,重寫該方法。

7)BeanFactoryAware.setBeanFactory
setBeanName之后調(diào)用,該方法作用是讓bean類知道自己所在的BeanFactory的屬性(傳入bean所在BeanFactory類型參數(shù))
實(shí)現(xiàn):bean類實(shí)現(xiàn)BeanFactoryAware接口,重寫該方法。

8)BeanPostProcessor.postProcessBeforeInitialization
BeanPostProcessor作用是對(duì)bean實(shí)例化,初始化做些預(yù)處理操作。(具體看上一篇文章 講 BeanPostProcessor)
實(shí)現(xiàn):寫一個(gè)類,實(shí)現(xiàn)BeanPostProcessor,重寫該方法,注意返回類型為Object,默認(rèn)返回的是null,但需要返回參數(shù)中的bean。然后在Spring配置文件中加入這個(gè)bean

9)bean里面 @PostConstruct 注解標(biāo)注的方法

10)InitializingBean.afterPropertiesSet
在Bean加載完成后,執(zhí)行方法。
實(shí)現(xiàn):bean類實(shí)現(xiàn) InitializingBean 接口。重寫該方法,執(zhí)行初始化工作。但這種方法和Spring耦合,并不推薦(這一點(diǎn)和DisposableBean一樣)

11)XML文件中 bean配置的 init-method
xml文件中,bean標(biāo)簽的 init-method屬性,可以指定方法。

12)BeanPostProcessor.postProcessAfterInitialization
在bean初始化之后,執(zhí)行的方法。
實(shí)現(xiàn)方式和第8步一樣。

銷毀過程

1)bean里面 @PreDestory 注解標(biāo)注的方法

2)DisposableBean.destory
bean銷毀前執(zhí)行的方法。(并不推薦)
實(shí)現(xiàn):bean類實(shí)現(xiàn) DisposableBean 接口,重寫該方法即可。

3)XML文件中 bean配置的destory-method
xml文件中,bean標(biāo)簽的 destory-method屬性。可以指定方法。



明確一下執(zhí)行順序

在配置了BeanProcessor,InstantiationAwareBeanPostProcessor ,實(shí)現(xiàn)了InitalizingBean,Bean配置了Init-method,destory-method
代碼中指定了 @PostConstruct,@PreDestroy 這些方法后。
Bean初始化時(shí)和銷毀時(shí),具體執(zhí)行順序是什么呢?

代碼如下:

//自定義Bean,實(shí)現(xiàn)InitializingBean 接口
public class BeanLifeCycleDemo implements InitializingBean {
    public BeanLifeCycleDemo() {
        System.out.println("> Constructor");
    }

    @Override
    public void afterPropertiesSet() throws Exception {
        System.out.println("> InitializingBean.afterPropertiesSet");
    }

    public void initMethod(){
        System.out.println("> init-method");
    }
    public void destoryMethod(){
        System.out.println("> destory-method");
    }


    @PostConstruct
    public void postConstructMethod(){
        System.out.println("> postConstruct");
    }
    @PreDestroy
    public void preDestoryMethod(){
        System.out.println("> preDestory");
    }
}

//自定義BeanPostProcessor
public class CustomBeanPostProcessor implements BeanPostProcessor {

    @Nullable
    @Override
    public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
        System.out.println("> CustomBeanPostProcessor.postProcessBeforeInitialization");
        return bean;
    }

    @Nullable
    @Override
    public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
        System.out.println("> CustomBeanPostProcessor.postProcessAfterInitialization");
        return bean;
    }
}

//自定義 InstantiationAwareBeanPostProcessor 
public class CustomInstantiationAwareBeanPostProcessor implements InstantiationAwareBeanPostProcessor {

    @Nullable
    @Override
    public Object postProcessBeforeInstantiation(Class<?> beanClass, String beanName) throws BeansException {
        System.out.println("> InstantiationAwareBeanPostProcessor.postProcessBeforeInstantiation");
        return null;
    }

    @Override
    public boolean postProcessAfterInstantiation(Object bean, String beanName) throws BeansException {
        System.out.println("> InstantiationAwareBeanPostProcessor.postProcessAfterInstantiation");
        return true;
    }

    @Nullable
    @Override
    public PropertyValues postProcessPropertyValues(PropertyValues pvs, PropertyDescriptor[] pds, Object bean, String beanName) throws BeansException {
        System.out.println("> InstantiationAwareBeanPostProcessor.postProcessPropertyValues");
        return pvs;
    }
}

//配置如下:

<bean id="beanLifeCycleDemo" class="com.antony.BeanLifeCycleDemo" init-method="initMethod" destroy-method="destoryMethod"></bean>
<bean id="customBeanPostProcessor" class="com.antony.CustomBeanPostProcessor"></bean>
<bean id="customInstantiationAwareBeanPostProcessor" class="com.antony.CustomInstantiationAwareBeanPostProcessor"></bean>



Bean初始化時(shí),方法執(zhí)行結(jié)果如下

> InstantiationAwareBeanPostProcessor.postProcessBeforeInstantiation
> Constructor
> InstantiationAwareBeanPostProcessor.postProcessAfterInstantiation
> InstantiationAwareBeanPostProcessor.postProcessPropertyValues
> CustomBeanPostProcessor.postProcessBeforeInitialization
> postConstruct (@PostConstruct注解的方法)
> InitializingBean.afterPropertiesSet
> init-method
> CustomBeanPostProcessor.postProcessAfterInitialization

在Bean銷毀時(shí),方法的執(zhí)行順序?yàn)?/strong>:

> preDestory (@PreDestory注解的方法)
> DisposableBean.destory
> destory-method



(如果有什么錯(cuò)誤或者建議,歡迎留言指出)
(本文內(nèi)容是對(duì)各個(gè)知識(shí)點(diǎn)的轉(zhuǎn)載整理,用于個(gè)人技術(shù)沉淀,以及大家學(xué)習(xí)交流用)


參考資料:

SpringBean生命周期詳解
spring InitializingBean init-method postConstruct 執(zhí)行順序
BeanPostProcessor與InitializingBean接口的關(guān)系和應(yīng)用
InitializingBean與DisposableBean總結(jié)



問題:Spring 在什么時(shí)候 執(zhí)行配置的 destory方法?(什么時(shí)候決定Bean被銷毀)

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容