Spring初始化Bean的三種方式

常用的設(shè)定方式有以下三種:
通過實現(xiàn) InitializingBean/DisposableBean 接口來定制初始化之后/銷毀之前的操作方法;
通過 @Bean的 initMethod/destroyMethod 屬性指定初始化之后 /銷毀之前調(diào)用的操作方法;
在指定方法上加上@PostConstruct 或@PreDestroy注解來制定該方法是在初始化之后還是銷毀之前調(diào)用。

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");  
    }  
}  

輸出結(jié)果:
InitSequenceBean: constructor
InitSequenceBean: postConstruct
InitSequenceBean: afterPropertiesSet
InitSequenceBean: init-method

通過上述輸出結(jié)果,說明三種初始化的順序是:
Constructor > @PostConstruct > InitializingBean > init-method

原因:
@PostConstruct注解后的方法在BeanPostProcessor前置處理器中就被執(zhí)行了。我們知道BeanPostProcessor接口是一個回調(diào)的作用,Spring容器的每個受管Bean在調(diào)用初始化方法之前,都會獲得BeanPostProcessor接口實現(xiàn)類的一個回調(diào)。在BeanPostProcessor的方法中有一段邏輯就是會判斷當前被回調(diào)的bean的方法中有沒有被initAnnotationType/destroyAnnotationType注釋,如果有,則添加到init/destroy隊列中,后續(xù)一一執(zhí)行。initAnnotationType/destroyAnnotationType注解就是@PostConstruct/@PreDestroy。所以@PostConstruct當然要先于InitializingBean和init-method執(zhí)行了。

image

從圖中,我們可以看到實例化Bean的過程中有以下幾個節(jié)點:
1)設(shè)置屬性值;
2)調(diào)用Bean中的BeanNameAware.setBeanName()方法,如果該Bean實現(xiàn)了BeanNameAware接口;
3)調(diào)用Bean中的BeanFactoryAware.setBeanFactory()方法,如果該Bean實現(xiàn)了BeanFactoryAware接口;
4)調(diào)用BeanPostProcessors.postProcessBeforeInitialization()方法;@PostConstruct注解后的方法就是在這里被執(zhí)行的
5)調(diào)用Bean中的afterPropertiesSet方法,如果該Bean實現(xiàn)了InitializingBean接口;
6)調(diào)用Bean中的init-method,通常是在配置bean的時候指定了init-method,例如:<bean class="beanClass" init-method="init"></bean>
7)調(diào)用BeanPostProcessors.postProcessAfterInitialization()方法;
8)如果該Bean是單例的,則當容器銷毀并且該Bean實現(xiàn)了DisposableBean接口的時候,調(diào)用destory方法;如果該Bean是prototype,則將準備好的Bean提交給調(diào)用者,后續(xù)不再管理該Bean的生命周期。

image.png
image.png
image.png
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

友情鏈接更多精彩內(nèi)容