1. 程式人生 > >Spring Bean初始化之後執行指定方法

Spring Bean初始化之後執行指定方法

轉載:https://blog.csdn.net/forever7107/article/details/76446544

常用的設定方式有以下三種:
通過實現 InitializingBean/DisposableBean 介面來定製初始化之後/銷燬之前的操作方法;
通過 <bean> 元素的 init-method/destroy-method屬性指定初始化之後 /銷燬之前呼叫的操作方法;
在指定方法上加上@PostConstruct 或@PreDestroy註解來制定該方法是在初始化之後還是銷燬之前呼叫。 


public class InitSequenceBean implements InitializingBean {  
   
    public InitSequenceBean() {  
       System.out.println("InitSequenceBean: constructor");  
    }  
     
    @PostConstruct  
    public void postConstruct() {  
       System.out.println("InitSequenceBean: postConstruct");  
    }  
     
    public void initMethod() {  
       System.out.println("InitSequenceBean: init-method");  
    }  
     
    @Override  
    public void afterPropertiesSet() throws Exception {  
       System.out.println("InitSequenceBean: afterPropertiesSet");  
    }  
}  


  
並且在配置檔案中新增如下Bean定義:
<bean class="InitSequenceBean" init-method="initMethod"></bean>

輸出結果:
InitSequenceBean: constructor
InitSequenceBean: postConstruct
InitSequenceBean: afterPropertiesSet
InitSequenceBean: init-method
 
通過上述輸出結果,說明三種初始化的順序是:
Constructor > @PostConstruct > InitializingBean > init-method

原因:
@PostConstruct註解後的方法在BeanPostProcessor前置處理器中就被執行了。我們知道BeanPostProcessor介面是一個回撥的作用,Spring容器的每個受管Bean在呼叫初始化方法之前,都會獲得BeanPostProcessor介面實現類的一個回撥。在BeanPostProcessor的方法中有一段邏輯就是會判斷當前被回撥的bean的方法中有沒有被initAnnotationType/destroyAnnotationType註釋,如果有,則新增到init/destroy佇列中,後續一一執行。initAnnotationType/destroyAnnotationType註解就是@PostConstruct/@PreDestroy。所以@PostConstruct當然要先於InitializingBean和init-method執行了。

從圖中,我們可以看到例項化Bean的過程中有以下幾個節點:
1)設定屬性值;
2)呼叫Bean中的BeanNameAware.setBeanName()方法,如果該Bean實現了BeanNameAware介面;
3)呼叫Bean中的BeanFactoryAware.setBeanFactory()方法,如果該Bean實現了BeanFactoryAware介面;
4)呼叫BeanPostProcessors.postProcessBeforeInitialization()方法;@PostConstruct註解後的方法就是在這裡被執行的
5)呼叫Bean中的afterPropertiesSet方法,如果該Bean實現了InitializingBean介面;
6)呼叫Bean中的init-method,通常是在配置bean的時候指定了init-method,例如:<bean class="beanClass" init-method="init"></bean>
7)呼叫BeanPostProcessors.postProcessAfterInitialization()方法;
8)如果該Bean是單例的,則當容器銷燬並且該Bean實現了DisposableBean介面的時候,呼叫destory方法;如果該Bean是prototype,則將準備好的Bean提交給呼叫者,後續不再管理該Bean的生命週期。