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

二、InitializingBean擴展
構(gòu)造方法、注解postConstruct,實現(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();
}
}
程序啟動在日志中看到如下信息:

通過啟動日志我們可以看出執(zhí)行順序優(yōu)先級:構(gòu)造方法 > postConstruct >afterPropertiesSet > init方法。
在Spring初始化bean的時候,如果該bean實現(xiàn)了InitializingBean接口,并且同時在配置了init-method,系統(tǒng)則是先調(diào)用afterPropertieSet()方法,然后再調(diào)用init-method中指定的方法。
那么這種方式在spring中是怎么實現(xiàn)的呢,通過查看Spring加載bean的源碼類AbstractAutowiredCapableBeanFactory可以看出其中的奧妙,AbstractAutowiredCapableBeanFactory類中的invokeInitMethods說的非常清楚,如下:
protected void invokeInitMethods(String beanName, final Object bean, RootBeanDefinition mbd) throws Throwable {
//判斷該bean是否實現(xiàn)了實現(xiàn)了InitializingBean接口,如果實現(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)) {
//進一步查看該方法的源碼,可以發(fā)現(xiàn)init-method方法中指定的方法是通過反射實現(xiàn)
invokeCustomInitMethod(beanName, bean, mbd);
}
}
}
總結(jié)
1、Spring為bean提供了兩種初始化bean的方式,實現(xiàn)InitializingBean接口,實現(xiàn)afterPropertiesSet方法,或者在配置文件中通過init-method指定,兩種方式可以同時使用。
2、實現(xiàn)InitializingBean接口是直接調(diào)用afterPropertiesSet方法,比通過反射調(diào)用init-method指定的方法效率要高一點,但是init-method方式消除了對spring的依賴。
3、如果調(diào)用afterPropertiesSet方法時出錯,則不調(diào)用init-method指定的方法。
到此這篇關于Spring中InitializingBean的使用詳細解析的文章就介紹到這了,更多相關InitializingBean的使用內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!
相關文章
Spring實戰(zhàn)之FileSystemResource加載資源文件示例
這篇文章主要介紹了Spring實戰(zhàn)之FileSystemResource加載資源文件,結(jié)合實例形式分析了spring FileSystemResource加載xml資源文件的具體實現(xiàn)步驟與相關操作技巧,需要的朋友可以參考下2019-12-12
springboot結(jié)合vue實現(xiàn)增刪改查及分頁查詢
本文主要介紹了springboot結(jié)合vue實現(xiàn)增刪改查及分頁查詢,文中通過示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下2021-09-09
MyBatis源碼解析——獲取SqlSessionFactory方式
這篇文章主要介紹了MyBatis源碼解析——獲取SqlSessionFactory方式,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教2021-12-12

