Spring中InitializingBean的使用詳細(xì)解析
一、InitializingBean作用
InitializingBean簡(jiǎn)介:
InitializingBean是Spring提供的拓展性接口,InitializingBean接口為bean提供了屬性初始化后的處理方法,它只有一個(gè)afterPropertiesSet方法,凡是繼承該接口的類(lèi),在bean的屬性初始化后都會(huì)執(zhí)行該方法。
InitializingBean用法 自定義MyInitializingBean實(shí)現(xiàn)InitializingBean接口
@Component
public class MyInitializingBean implements InitializingBean {
@Override
public void afterPropertiesSet() throws Exception {
System.out.println("我是啟動(dòng)時(shí)加載...");
}
}
程序啟動(dòng)在日志中看到如下信息:

二、InitializingBean擴(kuò)展
構(gòu)造方法、注解postConstruct,實(shí)現(xiàn)InitializingBean方法afterPropertiesSet,bean初始化init方法執(zhí)行順序。
@Component
public class MyInitializingBean implements InitializingBean {
public MyInitializingBean() {
System.out.println("我是MyInitializingBean構(gòu)造方法執(zhí)行...");
}
@Override
public void afterPropertiesSet() throws Exception {
System.out.println("我是afterPropertiesSet方法執(zhí)行...");
}
@PostConstruct
public void postConstruct() {
System.out.println("我是postConstruct方法執(zhí)行...");
}
public void init(){
System.out.println("我是init方法執(zhí)行...");
}
@Bean(initMethod = "init")
public MyInitializingBean test() {
return new MyInitializingBean();
}
}
程序啟動(dòng)在日志中看到如下信息:

通過(guò)啟動(dòng)日志我們可以看出執(zhí)行順序優(yōu)先級(jí):構(gòu)造方法 > postConstruct >afterPropertiesSet > init方法。
在Spring初始化bean的時(shí)候,如果該bean實(shí)現(xiàn)了InitializingBean接口,并且同時(shí)在配置了init-method,系統(tǒng)則是先調(diào)用afterPropertieSet()方法,然后再調(diào)用init-method中指定的方法。
那么這種方式在spring中是怎么實(shí)現(xiàn)的呢,通過(guò)查看Spring加載bean的源碼類(lèi)AbstractAutowiredCapableBeanFactory可以看出其中的奧妙,AbstractAutowiredCapableBeanFactory類(lèi)中的invokeInitMethods說(shuō)的非常清楚,如下:
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<Object>() {
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指定的方法效率要高一點(diǎn),但是init-method方式消除了對(duì)spring的依賴(lài)。
3、如果調(diào)用afterPropertiesSet方法時(shí)出錯(cuò),則不調(diào)用init-method指定的方法。
到此這篇關(guān)于Spring中InitializingBean的使用詳細(xì)解析的文章就介紹到這了,更多相關(guān)InitializingBean的使用內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
一篇文章帶你了解一些Java反射的學(xué)習(xí)記錄
java反射機(jī)制是一個(gè)很好用的東西,用它可以解決很多死的東西,因?yàn)榉瓷錂C(jī)制的靈活行很大,有了他,我們就不要花太多的時(shí)間來(lái)寫(xiě)操做數(shù)據(jù)庫(kù)的代碼了,這個(gè)可以很大的減少開(kāi)發(fā)時(shí)間,而且代碼的可讀性好2021-09-09
詳解Springboot2.3集成Spring security 框架(原生集成)
這篇文章主要介紹了詳解Springboot2.3集成Spring security 框架(原生集成),文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2020-08-08
springboot+redis過(guò)期事件監(jiān)聽(tīng)實(shí)現(xiàn)過(guò)程解析
這篇文章主要介紹了springboot+redis過(guò)期事件監(jiān)聽(tīng)實(shí)現(xiàn)過(guò)程解析,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下2020-03-03
why在重寫(xiě)equals時(shí)還必須重寫(xiě)hashcode方法分享
首先我們先來(lái)看下String類(lèi)的源碼:可以發(fā)現(xiàn)String是重寫(xiě)了Object類(lèi)的equals方法的,并且也重寫(xiě)了hashcode方法2013-10-10
Java MySQL動(dòng)態(tài)語(yǔ)句編寫(xiě)實(shí)現(xiàn)方式
這篇文章主要介紹了Java MySQL動(dòng)態(tài)語(yǔ)句編寫(xiě)實(shí)現(xiàn)方式,本文通過(guò)實(shí)例代碼給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友參考下吧2025-04-04
java判斷中文字符串長(zhǎng)度的簡(jiǎn)單實(shí)例
下面小編就為大家?guī)?lái)一篇java判斷中文字符串長(zhǎng)度的簡(jiǎn)單實(shí)例。小編覺(jué)得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧2017-01-01
Java中的模板模式說(shuō)明與實(shí)現(xiàn)
這篇文章主要介紹了Java中的模板模式說(shuō)明與實(shí)現(xiàn),模板方法模式,又叫模板模式,在一個(gè)抽象類(lèi)公開(kāi)定義了執(zhí)行它的方法的模板,它的子類(lèi)可以更需要重寫(xiě)方法實(shí)現(xiàn),但可以成為典型類(lèi)中定義的方式進(jìn)行,需要的朋友可以參考下2023-10-10
zuulGateway 通過(guò)filter統(tǒng)一修改返回值的操作
這篇文章主要介紹了zuulGateway 通過(guò)filter統(tǒng)一修改返回值的操作,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧2020-10-10
使用Java模擬鼠標(biāo)和鍵盤(pán)的詳細(xì)操作步驟
這篇文章主要介紹了使用Java模擬鼠標(biāo)和鍵盤(pán)的詳細(xì)操作步驟,要運(yùn)行上面提供的Java程序,您需要遵循幾個(gè)步驟來(lái)設(shè)置Java環(huán)境、編寫(xiě)程序代碼,并執(zhí)行該程序,文中有相關(guān)的代碼示例,需要的朋友可以參考下2024-05-05
一文講解Java的String、StringBuffer和StringBuilder的使用與區(qū)別
String是不可變的字符序列,而StringBuffer和StringBuilder是可變的字符序列,本文就來(lái)詳細(xì)的介紹一下Java的String、StringBuffer和StringBuilder的使用與區(qū)別,感興趣的可以了解一下2024-03-03

