应用场景
当我们的web项目启动时,或许我们需要做一些事情;今天其他的方式就不提了,我们说一下如何监听spring启动,来做一些事情。
解决方案
在项目中创建一个类继承spring的ApplicationListener监听,并监控ContextRefreshedEvent事件(容器初始化完成事件)
如下:
package com.common.listener;
import org.springframework.context.ApplicationListener;
import org.springframework.context.event.ContextRefreshedEvent;
import org.springframework.stereotype.Component;
@Component("BeanDefineConfigue")
public class BeanDefineConfigue implements ApplicationListener<ContextRefreshedEvent> {
/**
* 当一个ApplicationContext被初始化或刷新触发
* ContextRefreshedEvent为初始化完毕事件,spring还有很多事件可以利用
*/
@Override
public void onApplicationEvent(ContextRefreshedEvent event) {
System.out.println("spring容器完成初始化!");
}
}
然后再spring中,实例化这个类:我们可以采用注解或者spring.xml配置文件中声明。
如果使用MVC
如果我们在项目中使用了spring MVC,那么spring的applicationontext和spring 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")
spring其他事件
spring中已经内置的几种事件:
- ContextRefreshedEvent
- ContextStartedEvent
- RequestHandleEvent
- ContextClosedEvent
- ContextStoppedEvent
因为工作原因,暂时没有时间弄这些,有时间补上