您好,登錄后才能下訂單哦!
關于在spring 容器初始化 bean 和銷毀前所做的操作定義方式有三種:
第一種:通過注解@PostConstruct 和 @PreDestroy 方法 實現初始化和銷毀bean之前進行的操作
import javax.annotation.PostConstruct; import javax.annotation.PreDestroy; public class DataInitializer{ @PostConstruct public void initMethod() throws Exception { System.out.println("initMethod 被執行"); } @PreDestroy public void destroyMethod() throws Exception { System.out.println("destroyMethod 被執行"); } }
第二種是:通過 在xml中定義init-method 和 destory-method方法
public class DataInitializer{ public void initMethod() throws Exception { System.out.println("initMethod 被執行"); } public void destroyMethod() throws Exception { System.out.println("destroyMethod 被執行"); } }
第三種是: 通過bean實現InitializingBean和 DisposableBean接口
import org.springframework.beans.factory.DisposableBean; public class DataInitializer implements InitializingBean,DisposableBean{ @Override public void afterPropertiesSet() throws Exception { System.out.println("afterPropertiesSet 被執行"); } @Override public void destroy() throws Exception { System.out.println("destroy 被執行"); } }
其中第一種和第二種是同一種形式,只不過一種xml配置,另外一種采用注解形式罷了,有很大區別的是第三種,如果同一個bean同時采用兩種方式初始化的時候執行某個方法,首先在執行順序上就會體現出來。
先執行afterPropertiesSet(),后執行initMethod()
這里我們看下源碼
這方式在spring中是怎么實現的?
通過查看spring的加載bean的源碼類(AbstractAutowireCapableBeanFactory)可看出其中奧妙
AbstractAutowireCapableBeanFactory類中的invokeInitMethods講解的非常清楚,源碼如下:
protected void invokeInitMethods(String beanName, final Object bean, RootBeanDefinition mbd) throws Throwable { //判斷該bean是否實現了實現了InitializingBean接口,如果實現了InitializingBean接口,則只掉調用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 { //直接調用afterPropertiesSet ((InitializingBean) bean).afterPropertiesSet(); return null; } },getAccessControlContext()); } catch (PrivilegedActionException pae) { throw pae.getException(); } } else { //直接調用afterPropertiesSet ((InitializingBean) bean).afterPropertiesSet(); } } if (mbd != null) { String initMethodName = mbd.getInitMethodName(); //判斷是否指定了init-method方法,如果指定了init-method方法,則再調用制定的init-method if (initMethodName != null && !(isInitializingBean && "afterPropertiesSet".equals(initMethodName)) && !mbd.isExternallyManagedInitMethod(initMethodName)) { //進一步查看該方法的源碼,可以發現init-method方法中指定的方法是通過反射實現 invokeCustomInitMethod(beanName, bean, mbd); } }
總結:
1:spring為bean提供了兩種初始化bean的方式,實現InitializingBean接口,實現afterPropertiesSet方法,或者在配置文件中同過init-method指定,兩種方式可以同時使用
2:實現InitializingBean接口是直接調用afterPropertiesSet方法,比通過反射調用init-method指定的方法效率相對來說要高點。但是init-method方式消除了對spring的依賴
3:如果調用afterPropertiesSet方法時出錯,則不調用init-method指定的方法。
以上就是本文的全部內容,希望對大家的學習有所幫助,也希望大家多多支持億速云。
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。