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

spring容器載入完畢幹一件事情(利用ContextRefreshedEvent事件)

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

應用場景:很多時候我們想要在某個類載入完畢時幹某件事情,但是使用了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容器初始化完成後就會執行該方法。  
        }  
      }