Spring初始化Bean的三種方式


常用的設定方式有以下三種:
通過實現 InitializingBean/DisposableBean 接口來定制初始化之后/銷毀之前的操作方法;
通過 @Bean的 initMethod/destroyMethod 屬性指定初始化之后 /銷毀之前調用的操作方法;
在指定方法上加上@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() {  
      // 使用@Bean(initMethod="initMethod")聲明
       System.out.println("InitSequenceBean: init-method");  
    }  
     
    @Override  
    public void afterPropertiesSet() throws Exception {  
       System.out.println("InitSequenceBean: afterPropertiesSet");  
    }  
}  

輸出結果:
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執行了。

image

從圖中,我們可以看到實例化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,例如:
7)調用BeanPostProcessors.postProcessAfterInitialization()方法;
8)如果該Bean是單例的,則當容器銷毀並且該Bean實現了DisposableBean接口的時候,調用destory方法;如果該Bean是prototype,則將准備好的Bean提交給調用者,后續不再管理該Bean的生命周期。

image.png

image.png

image.png


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM