Spring的ApplicationContext
提供了支持事件和代碼中監聽器的功能。java
咱們能夠建立bean用來監聽在ApplicationContext
中發佈的事件。ApplicationEven
t類和在ApplicationContext
接口
中處理的事件,若是一個bean實現了ApplicationListener
接口,當一個ApplicationEvent
被髮布之後,bean會自動被通知。web
1
2
3
4
5
6
7
8
|
public
class
AllApplicationEventListener
implements
ApplicationListener < ApplicationEvent >
{
@Override
public
void
onApplicationEvent(ApplicationEvent applicationEvent)
{
//process event
}
}
|
Spring 提供瞭如下5中標準的事件:spring
應用場景:不少時候咱們想要在某個類加載完畢時幹某件事情,可是使用了spring管理對象,咱們這個類引用了其餘類(多是更復雜的關聯),因此當咱們去使用這個類作事情時發現包空指針錯誤,這是由於咱們這個類有可能已經初始化完成,可是引用的其餘類不必定初始化完成,因此發生了空指針錯誤,解決方案以下:
一、寫一個類繼承spring的ApplicationListener監聽,並監控ContextRefreshedEvent事件(容易初始化完成事件)
二、定義簡單的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")mvc