本文主要介紹三個初始化的方式,分別是@PostConstruct,InitializingBean,以及SmartInitializingSingleton這三個,咱們直接三個一塊兒用,來看看代碼哈。app
@Component
public class TestP implements InitializingBean, SmartInitializingSingleton {
@PostConstruct
public void test() {
System.out.println("@PostConstruct");
}
@Override
public void afterPropertiesSet() throws Exception {
// InitializingBean 的方法
System.out.println("afterPropertiesSet");
}
@Override
public void afterSingletonsInstantiated() {
// SmartInitializingSingleton 的方法
System.out.println("afterSingletonsInstantiated");
}
}
複製代碼
代碼很簡單,咱們來看看容器啓動後的結果:ide
調用初始化的代碼位於AbstractAutowireCapableBeanFactory中的initializeBean方法中post
protected Object initializeBean(final String beanName, final Object bean, RootBeanDefinition mbd) {
// 調用幾個Aware接口
if (System.getSecurityManager() != null) {
AccessController.doPrivileged(new PrivilegedAction<Object>() {
@Override
public Object run() {
invokeAwareMethods(beanName, bean);
return null;
}
}, getAccessControlContext());
}
else {
invokeAwareMethods(beanName, bean);
}
// 調用全部的BeanPostProcessor的postProcessBeforeInitialization
Object wrappedBean = bean;
if (mbd == null || !mbd.isSynthetic()) {
wrappedBean = applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName);
}
try {
// 調用InitializingBean的方法和自定義初始化方法
invokeInitMethods(beanName, wrappedBean, mbd);
}catch (Throwable ex) {
throw new BeanCreationException(
(mbd != null ? mbd.getResourceDescription() : null),
beanName, "Invocation of init method failed", ex);
}
// 執行全部BeanPostProcessor的postProcessAfterInitialization方法
if (mbd == null || !mbd.isSynthetic()) {
wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);
}
return wrappedBean;
}
複製代碼
在這個方法中,咱們很明顯的能夠看到,InitializingBean的執行位置,那麼@PostConstruct是在哪裏執行的呢?通過debug,咱們能夠發現它是在調用全部的BeanPostProcessor的postProcessBeforeInitialization的時候被執行的(CommonAnnotationBeanPostProcessor中)。而後SmartInitializingSingleton這個東西須要先說一下,Spring4.0的時候是沒有這個東西的,這個是4.1以後加入進來的,這個也能夠用來作初始化以後的一些操做,那麼它又是何時被執行的呢?咱們能夠在DefaultListableBeanFactory中的preInstantiateSingletons中最後幾行中發現:ui
而這個時候,全部的Bean都已經被初始化了。因此咱們在這裏作一個小小的總結:這三個初始化的方法,執行前後順序是@PostConstruct,而後是InitializingBean,最後是SmartInitializingSingleton。舉個使用上的小例子,若是A bean要依賴B bean初始化產生的數據的話,那麼就可讓A來實現SmartInitializingSingleton,B來實現InitializingBean或者使用@PostConstruct,InitializingBean和@PostConstruct這兩個初始化的方式在絕大多數狀況下都沒什麼差異。另外須要注意的是這三個初始化的方法,都不要和以前的BeanFactoryPostProcessor以及BeanPostProcessor一塊兒用,由於是在容器不一樣階段來作的事情,好比我舉一個例子:spa
@Component
public class AProcessor implements BeanPostProcessor, PriorityOrdered {
@PostConstruct
public void test() {
System.out.println("AProcessor @PostConstruct");
}
@Override
public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
System.out.println("aa");
return null;
}
@Override
public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
System.out.println("bb");
return null;
}
@Override
public int getOrder() {
return 0;
}
}
複製代碼
這個類實現了BeanPostProcessor 和PriorityOrdered 這兩個接口,而後咱們啓動以後發現@PostConstruct裏面的東西並無被執行,這個緣由是由於這個類初始化的時候用做執行@PostConstruct的BeanPostProcessor 尚未被初始化,因此固然沒法執行嘍,這只不過是我隨隨便便就想到的一個,還有可能又其餘坑的,因此說盡量分開用。debug
寫文章不易,尤爲完了要對一個龐大的東西作總結更爲不易,因此你的贊對我很重要,求點個贊🥺~code