spring容器加载完毕做一件事情(利用ContextRefreshedEvent事件)
原文地址:http://zhaoshijie.iteye.com/blog/1974682
應用場景:很多時候我們想要在某個類加載完畢時干某件事情,但是使用了spring管理對象,我們這個類引用了其他類(可能是更復雜的關聯),所以當我們去使用這個類做事情時發現包空指針錯誤,這是因為我們這個類有可能已經初始化完成,但是引用的其他類不一定初始化完成,所以發生了空指針錯誤,解決方案如下:?
1、寫一個類繼承spring的ApplicationListener監聽,并監控ContextRefreshedEvent事件(容易初始化完成事件)?
2、定義簡單的bean:<bean id="beanDefineConfigue" class="com.creatar.portal.webservice.BeanDefineConfigue"></bean>?
或者直接使用@Component("BeanDefineConfigue")注解方式?
完整的類如下:?
package com.creatar.portal.webservice;?
import org.springframework.context.ApplicationListener;?
import org.springframework.context.event.ContextRefreshedEvent;?
import org.springframework.stereotype.Component;?
@Component("BeanDefineConfigue")?
public class BeanDefineConfigue implements?
ApplicationListener<ContextRefreshedEvent> {//ContextRefreshedEvent為初始化完畢事件,spring還有很多事件可以利用?
// @Autowired?
// private IRoleDao roleDao;?
/**?
* 當一個ApplicationContext被初始化或刷新觸發?
*/?
@Override?
public void onApplicationEvent(ContextRefreshedEvent event) {?
// roleDao.getUserList();//spring容器初始化完畢加載用戶列表到內存?
System.out.println("spring容易初始化完畢================================================");?
}?
}?
或者使用xml配置方式(非注解),簡單配置個bean即可?
<bean id="beanDefineConfigue" class="com.creatar.portal.webservice.BeanDefineConfigue"></bean>?
其他定義方式:?
完整的類如下:?
package com.creatar.portal.webservice;?
import java.util.ArrayList;?
import java.util.List;?
import org.springframework.context.ApplicationEvent;?
import org.springframework.context.ApplicationListener;?
import org.springframework.context.event.ContextRefreshedEvent;?
import org.springframework.stereotype.Component;?
@Component("BeanDefineConfigue2")?
public class BeanDefineConfigue2 implements ApplicationListener<ApplicationEvent> {?
List<String> list = new ArrayList<String>();?
/**?
* 當一個ApplicationContext被初始化或刷新觸發?
*/?
@Override?
public void onApplicationEvent(ApplicationEvent event) {?
if (event instanceof ContextRefreshedEvent) {?
System.out.println("spring容易初始化完畢================================================888");?
}?
}?
}?
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")
?
參考文獻:
http://wiki.jikexueyuan.com/project/spring/event-handling-in-spring.html
轉載于:https://www.cnblogs.com/davidwang456/p/5125142.html
《新程序員》:云原生和全面數字化實踐50位技術專家共同創作,文字、視頻、音頻交互閱讀總結
以上是生活随笔為你收集整理的spring容器加载完毕做一件事情(利用ContextRefreshedEvent事件)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Let's do our own ful
- 下一篇: zookeeper应用实例