Spring中InitializingBean的使用詳細(xì)解析
一、InitializingBean作用
InitializingBean簡(jiǎn)介:
InitializingBean是Spring提供的拓展性接口,InitializingBean接口為bean提供了屬性初始化后的處理方法,它只有一個(gè)afterPropertiesSet方法,凡是繼承該接口的類,在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的源碼類AbstractAutowiredCapableBeanFactory可以看出其中的奧妙,AbstractAutowiredCapableBeanFactory類中的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的依賴。
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獲取文件的inode標(biāo)識(shí)符的方法
這篇文章主要介紹了java獲取文件的inode標(biāo)識(shí)符,本文通過(guò)實(shí)例代碼給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2022-04-04Spring實(shí)戰(zhàn)之FileSystemResource加載資源文件示例
這篇文章主要介紹了Spring實(shí)戰(zhàn)之FileSystemResource加載資源文件,結(jié)合實(shí)例形式分析了spring FileSystemResource加載xml資源文件的具體實(shí)現(xiàn)步驟與相關(guān)操作技巧,需要的朋友可以參考下2019-12-12Java日常練習(xí)題,每天進(jìn)步一點(diǎn)點(diǎn)(14)
下面小編就為大家?guī)?lái)一篇Java基礎(chǔ)的幾道練習(xí)題(分享)。小編覺(jué)得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧,希望可以幫到你2021-07-07Java實(shí)現(xiàn)學(xué)生管理系統(tǒng)詳解流程
這篇文章主要為大家詳細(xì)介紹了如何利用Java語(yǔ)言實(shí)現(xiàn)學(xué)生管理系統(tǒng),文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2022-06-06springboot結(jié)合vue實(shí)現(xiàn)增刪改查及分頁(yè)查詢
本文主要介紹了springboot結(jié)合vue實(shí)現(xiàn)增刪改查及分頁(yè)查詢,文中通過(guò)示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2021-09-09MyBatis源碼解析——獲取SqlSessionFactory方式
這篇文章主要介紹了MyBatis源碼解析——獲取SqlSessionFactory方式,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2021-12-12