13.Spring中初始化bean和銷毀bean的時(shí)候執(zhí)行某個(gè)方法的詳解

關(guān)于在spring容器初始化 bean 和銷毀前所做的操作定義方式有三種:

第一種:通過(guò)注解@PostConstruct

和 @PreDestroy 方法 實(shí)現(xiàn)初始化和銷毀bean之前進(jìn)行的操作

[java]view plaincopy

import?javax.annotation.PostConstruct;????

import?javax.annotation.PreDestroy;????


public?class?DataInitializer{?????

@PostConstruct??

public?void?initMethod()?throws?Exception?{??

System.out.println("initMethod?被執(zhí)行");??

????}??

@PreDestroy??

public?void?destroyMethod()?throws?Exception?{??

System.out.println("destroyMethod?被執(zhí)行");??

????}??

}??

第二種是:通過(guò) 在xml中定義init-method 和 ?destory-method方法

[java]view plaincopy

public?class?DataInitializer{??

public?void?initMethod()?throws?Exception?{??

System.out.println("initMethod?被執(zhí)行");??

????}??

public?void?destroyMethod()?throws?Exception?{??

System.out.println("destroyMethod?被執(zhí)行");??

????}??

}??

[html]view plaincopy

??

第三種是:?通過(guò)bean實(shí)現(xiàn)InitializingBean和 DisposableBean接口

[java]view plaincopy

import?org.springframework.beans.factory.DisposableBean;??


public?class?DataInitializer?implements?InitializingBean,DisposableBean{??


@Override??

public?void?afterPropertiesSet()?throws?Exception?{??

System.out.println("afterPropertiesSet?被執(zhí)行");??

????}??


@Override??

public?void?destroy()?throws?Exception?{??

System.out.println("destroy?被執(zhí)行");??

????}??


}??

其中第一種和第二種是同一種形式,只不過(guò)一種xml配置,另外一種采用注解形式罷了,有很大區(qū)別的是第三種,

如果同一個(gè)bean同時(shí)采用兩種方式初始化的時(shí)候執(zhí)行某個(gè)方法,首先在執(zhí)行順序上就會(huì)體現(xiàn)出來(lái)。

先執(zhí)行afterPropertiesSet(),

后執(zhí)行initMethod()

這里我們看下源碼

這方式在spring中是怎么實(shí)現(xiàn)的?

通過(guò)查看spring的加載bean的源碼類(AbstractAutowireCapableBeanFactory)可看出其中奧妙

AbstractAutowireCapableBeanFactory類中的invokeInitMethods講解的非常清楚,源碼如下:

[java]view plaincopy

protected?void?invokeInitMethods(String?beanName,?final?Object?bean,?RootBeanDefinition?mbd)??

throws?Throwable?{??

//判斷該bean是否實(shí)現(xiàn)了實(shí)現(xiàn)了InitializingBean接口,如果實(shí)現(xiàn)了InitializingBean接口,則只掉調(diào)用bean的afterPropertiesSet方法??

boolean?isInitializingBean?=?(bean?instanceof?InitializingBean);??

if?(isInitializingBean?&&?(mbd?==?null?||?!mbd.isExternallyManagedInitMethod("afterPropertiesSet")))?{??

if?(logger.isDebugEnabled())?{??

logger.debug("Invoking?afterPropertiesSet()?on?bean?with?name?'"?+?beanName?+?"'");??

??????}??


if?(System.getSecurityManager()?!=?null)?{??

try?{??

AccessController.doPrivileged(new?PrivilegedExceptionAction()?{??

public?Object?run()?throws?Exception?{??

//直接調(diào)用afterPropertiesSet??

??????????????????????((InitializingBean)?bean).afterPropertiesSet();??

return?null;??

??????????????????}??

??????????????},getAccessControlContext());??

}catch?(PrivilegedActionException?pae)?{??

throw?pae.getException();??

??????????}??

??????}??????????????????

else?{??

//直接調(diào)用afterPropertiesSet??

??????????((InitializingBean)?bean).afterPropertiesSet();??

??????}??

??}??

if?(mbd?!=?null)?{??

??????String?initMethodName?=?mbd.getInitMethodName();??

//判斷是否指定了init-method方法,如果指定了init-method方法,則再調(diào)用制定的init-method??

if?(initMethodName?!=?null?&&?!(isInitializingBean?&&?"afterPropertiesSet".equals(initMethodName))?&&??

??????????????!mbd.isExternallyManagedInitMethod(initMethodName))?{??

//進(jìn)一步查看該方法的源碼,可以發(fā)現(xiàn)init-method方法中指定的方法是通過(guò)反射實(shí)現(xiàn)??

??????????invokeCustomInitMethod(beanName,?bean,?mbd);??

??????}??

??}??

總結(jié):

1:spring為bean提供了兩種初始化bean的方式,實(shí)現(xiàn)InitializingBean接口,實(shí)現(xiàn)afterPropertiesSet方法,或者在配置文件中同過(guò)

init-method指定,兩種方式可以同時(shí)使用

2:實(shí)現(xiàn)InitializingBean接口是直接調(diào)用afterPropertiesSet方法,比通過(guò)反射調(diào)用init-method指定的方法效率相對(duì)來(lái)說(shuō)要高點(diǎn)。但是

init-method方式消除了對(duì)spring的依賴

3:如果調(diào)用afterPropertiesSet方法時(shí)出錯(cuò),則不調(diào)用init-method指定的方法。

?著作權(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)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

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

  • 一、設(shè)計(jì)模式的分類 總體來(lái)說(shuō)設(shè)計(jì)模式分為三大類: 創(chuàng)建型模式,共五種:工廠方法模式、抽象工廠模式、單例模式、建造者...
    RamboLI閱讀 836評(píng)論 0 1
  • 一、InitializingBean接口說(shuō)明 InitializingBean接口為bean提供了屬性初始化后的處...
    BUG弄潮兒閱讀 610評(píng)論 0 0
  • 文章部分內(nèi)容轉(zhuǎn)載自:http://blog.csdn.net/zhangerqing 一、設(shè)計(jì)模式的分類 總體來(lái)說(shuō)...
    j_cong閱讀 2,143評(píng)論 0 20
  • 創(chuàng)建 bean 在經(jīng)歷過(guò) AbstractAutowireCapableBeanFactory#createBea...
    仗劍詩(shī)篇閱讀 2,323評(píng)論 0 1
  • 每個(gè)人心底,都會(huì)有一個(gè)美麗的夢(mèng)吧! 有人夢(mèng)想仗劍走天涯,有人夢(mèng)想落筆成花;有人夢(mèng)想齊家治國(guó)平天下;有人夢(mèng)想,一個(gè)人...
    花開(kāi)脈脈閱讀 330評(píng)論 1 2

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