1. 程式人生 > >spring容器加載完畢做一件事情(利用ContextRefreshedEvent事件)

spring容器加載完畢做一件事情(利用ContextRefreshedEvent事件)

ref refresh display ras 方案 splay 區分 容器 and

關鍵字:spring容器加載完畢做一件事情(利用ContextRefreshedEvent事件)

應用場景:很多時候我們想要在某個類加載完畢時幹某件事情,但是使用了spring管理對象,我們這個類引用了其他類(可能是更復雜的關聯),所以當我們去使用這個類做事情時發現包空指針錯誤,這是因為我們這個類有可能已經初始化完成,但是引用的其他類不一定初始化完成,所以發生了空指針錯誤,解決方案如下:

1、寫一個類繼承spring的ApplicationListener監聽,並監控ContextRefreshedEvent事件(容易初始化完成事件)

2、定義簡單的bean ,直接用註解 @Component

完整的類如下

public class OrderAssistant implements ApplicationListener<ContextRefreshedEvent>{
@Override
	public void onApplicationEvent(ContextRefreshedEvent event) {
}

 spring其他事件:

spring中已經內置的幾種事件:

ContextClosedEvent 、ContextRefreshedEvent 、ContextStartedEvent 、ContextStoppedEvent 、RequestHandleEvent



後續研究:
applicationontext和使用MVC之後的webApplicationontext會兩次調用上面的方法,如何區分這個兩種容器呢?

但是這個時候,會存在一個問題,在web 項目中(spring mvc),系統會存在兩個容器,一個是root application context ,另一個就是我們自己的 projectName-servlet context(作為root application context的子容器)。

這種情況下,就會造成onApplicationEvent方法被執行兩次。為了避免上面提到的問題,我們可以只在root application context初始化完成後調用邏輯代碼,其他的容器的初始化完成,則不做任何處理,修改後代碼

如下:

@Override
public void onApplicationEvent(ContextRefreshedEvent event) {
if(event.getApplicationContext().getParent() == null){//root application context 沒有parent,他就是老大.
//需要執行的邏輯代碼,當spring容器初始化完成後就會執行該方法。
}
}


後續發現加上以上判斷還是能執行兩次,不加的話三次,最終研究結果使用以下判斷更加準確:event.getApplicationContext().getDisplayName().equals("Root WebApplicationContext") 

spring容器加載完畢做一件事情(利用ContextRefreshedEvent事件)