Spring—ContextRefreshedEvent

来源:互联网 发布:练音准的软件 编辑:程序博客网 时间:2024/06/08 05:47

在开发时有时候需要在整个应用开始运行时执行一些特定代码,比如初始化环境,准备测试数据、加载一些数据到内存等等。

在Spring中可以通过ApplicationListener来实现相关的功能,加载完成后触发contextrefreshedevent事件(上下文件刷新事件)

 

Java代码  收藏代码
  1. <bean id="testContextRefreshedEvent" class="com.sf.sfbuy2.context.filter.TestContextRefreshedEvent"></bean>  

 

Java代码  收藏代码
  1. import org.springframework.context.ApplicationListener;  
  2. import org.springframework.context.event.ContextRefreshedEvent;  
  3. import org.springframework.context.support.ClassPathXmlApplicationContext;  
  4.   
  5. public class TestContextRefreshedEvent implements ApplicationListener<ContextRefreshedEvent>{  
  6.   
  7.     @Override  
  8.     public void onApplicationEvent(ContextRefreshedEvent arg0) {  
  9.         System.out.println("Spring容器加载完成触发,可用于初始化环境,准备测试数据、加载一些数据到内存");  
  10.     }  
  11.       
  12.     public static void main(String[] args) {  
  13.         ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");  
  14.         context.close();  
  15.     }  
  16.   
  17. }  

 

但是这个时候,会存在一个问题,在web 项目中(spring mvc),系统会存在两个容器,一个是root application context ,另一个就是我们自己的 projectName-servlet  context(作为root application context的子容器)。

这种情况下,就会造成onApplicationEvent方法被执行两次。为了避免上面提到的问题,我们可以只在root application context初始化完成后调用逻辑代码,其他的容器的初始化完成,则不做任何处理,修改后代码

如下:

Java代码  收藏代码
  1. @Override  
  2.   public void onApplicationEvent(ContextRefreshedEvent event) {  
  3.       if(event.getApplicationContext().getParent() == null){//root application context 没有parent,他就是老大.  
  4.            //需要执行的逻辑代码,当spring容器初始化完成后就会执行该方法。  
  5.       }  
  6.   }  

参考:http://blog.csdn.net/u013400939/article/details/51460491


======================================================================================================================

ApplicationContext在运行期会自动检测到所有实现了ApplicationListener的bean对象,并将其作为事件接收对象。当ApplicationContext的publishEvent方法被触发时,每个实现了ApplicationListener接口的bean都会收到ApplicationEvent对象,每个ApplicationListener可根据事件类型只接收处理自己感兴趣的事件,比如上面的StudentAddListener只接收StudentAddEvent事件。


http://blog.csdn.net/liuwenbo0920/article/details/7263766(非常好)


http://yangyongbyjava.iteye.com/blog/1600581


http://www.th7.cn/Program/java/201408/271385.shtml(ApplicationListener接口中的onApplicationEvent被调用两次解决方案)

Spring监听&nbsp;ApplicationListener

[java] view plain copy
  1. import java.util.HashMap;  
  2. import java.util.Map;  
  3. import org.apache.commons.lang3.StringUtils;  
  4. import org.apache.log4j.Logger;  
  5. importorg.springframework.beans.factory.annotation.Autowired;  
  6. importorg.springframework.beans.factory.annotation.Qualifier;  
  7. import org.springframework.context.ApplicationContext;  
  8. import org.springframework.context.ApplicationListener;  
  9. importorg.springframework.context.event.ContextRefreshedEvent;  
  10. import org.springframework.stereotype.Component;  
  11.   
  12. @Component  
  13. public class InitDataListener implements  
  14.   ApplicationListener { //ContextRefreshedEvent为初始化完毕事件  
  15.  private static final Logger LOGGER =Logger  
  16.    .getLogger(InitDataListener.class);  
  17.  // 缓存管理器  
  18.  @Autowired  
  19.  @Qualifier("dictCacheManager")  
  20.  private DictCacheManager dictCacheManager;  
  21.  @Override  
  22.  public voidonApplicationEvent(ContextRefreshedEvent event) {  
  23.   final ApplicationContext app= event.getApplicationContext();  
  24.   if (null ==app.getParent()  
  25.     &&"Root WebApplicationContext".equals(app.getDisplayName())) { //当存在父子容器时,此判断很有用  
  26.    //读取字典配置  
  27.    Map config =new HashMap();  
  28.    try {  
  29.     config= PathUtil.getProperties("dataDictConfig.properties");  
  30.     finalString mKey = config.get("dataDictKey");  
  31.     if(StringUtils.isNotBlank(mKey)) {  
  32.      DictCacheManager.M_KEY= mKey;  
  33.     }  
  34.    } catch(Exception e) {  
  35.     LOGGER.error("Load\"dataDictConfig.properties\" failure!", e);  
  36.    }  
  37.    //判断是否立即加载数据字典到Redis  
  38.    if("false".equals(config.get("lazyLoad"))) { //立即加载数据字典数据到Redis缓存服务器  
  39.     dictCacheManager.init();  
  40.    }  
  41.   }  
  42.  }  
  43. }  
  44.   
  45. }  


参考:http://blog.csdn.net/yanfeng918/article/details/44780203





阅读全文
0 0