spring容器加载完毕做一件事情(利用ContextRefreshedEvent事件)
原文地址:http://zhaoshijie.iteye.com/blog/1974682
應(yīng)用場景:很多時候我們想要在某個類加載完畢時干某件事情,但是使用了spring管理對象,我們這個類引用了其他類(可能是更復(fù)雜的關(guān)聯(lián)),所以當(dāng)我們?nèi)ナ褂眠@個類做事情時發(fā)現(xiàn)包空指針錯誤,這是因?yàn)槲覀冞@個類有可能已經(jīng)初始化完成,但是引用的其他類不一定初始化完成,所以發(fā)生了空指針錯誤,解決方案如下:?
1、寫一個類繼承spring的ApplicationListener監(jiān)聽,并監(jiān)控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;?
/**?
* 當(dāng)一個ApplicationContext被初始化或刷新觸發(fā)?
*/?
@Override?
public void onApplicationEvent(ContextRefreshedEvent event) {?
// roleDao.getUserList();//spring容器初始化完畢加載用戶列表到內(nèi)存?
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>();?
/**?
* 當(dāng)一個ApplicationContext被初始化或刷新觸發(fā)?
*/?
@Override?
public void onApplicationEvent(ApplicationEvent event) {?
if (event instanceof ContextRefreshedEvent) {?
System.out.println("spring容易初始化完畢================================================888");?
}?
}?
}?
spring其他事件:?
spring中已經(jīng)內(nèi)置的幾種事件:?
ContextClosedEvent?? 、ContextRefreshedEvent? 、ContextStartedEvent? 、ContextStoppedEvent?? 、RequestHandleEvent?
后續(xù)研究:?
applicationontext和使用MVC之后的webApplicationontext會兩次調(diào)用上面的方法,如何區(qū)分這個兩種容器呢??
但是這個時候,會存在一個問題,在web 項(xiàng)目中(spring mvc),系統(tǒng)會存在兩個容器,一個是root application context ,另一個就是我們自己的 projectName-servlet context(作為root application context的子容器)。?
這種情況下,就會造成onApplicationEvent方法被執(zhí)行兩次。為了避免上面提到的問題,我們可以只在root application context初始化完成后調(diào)用邏輯代碼,其他的容器的初始化完成,則不做任何處理,修改后代碼?
如下:?
??? @Override??
????? public void onApplicationEvent(ContextRefreshedEvent event) {??
??????? if(event.getApplicationContext().getParent() == null){//root application context 沒有parent,他就是老大.??
???????????? //需要執(zhí)行的邏輯代碼,當(dāng)spring容器初始化完成后就會執(zhí)行該方法。??
??????? }??
????? }??
后續(xù)發(fā)現(xiàn)加上以上判斷還是能執(zhí)行兩次,不加的話三次,最終研究結(jié)果使用以下判斷更加準(zhǔn)確:event.getApplicationContext().getDisplayName().equals("Root WebApplicationContext")
?
參考文獻(xiàn):
http://wiki.jikexueyuan.com/project/spring/event-handling-in-spring.html
轉(zhuǎn)載于:https://www.cnblogs.com/davidwang456/p/5125142.html
《新程序員》:云原生和全面數(shù)字化實(shí)踐50位技術(shù)專家共同創(chuàng)作,文字、視頻、音頻交互閱讀總結(jié)
以上是生活随笔為你收集整理的spring容器加载完毕做一件事情(利用ContextRefreshedEvent事件)的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Let's do our own ful
- 下一篇: zookeeper应用实例