先上一段代码
// 继承ApplicationListener发布一个监听器,并没有指定范型(类似ApplicationListener< ContextRefreshedEvent >这样只能监听ContextRefreshedEvent事件)
// 所以,所有的发布事件全都可以被监听到
@Slf4j
@Component
public class AppApplicationListener implements ApplicationListener {
@Override
public void onApplicationEvent(ApplicationEvent event) {
// 1. ContextRefreshedEvent事件,在ApplicationContext完成刷新refreshed后调用
if (event instanceof ContextRefreshedEvent){
log.info("================:{}", "ContextRefreshedEvent");
}
if (event instanceof ContextStartedEvent){
log.info("================:{}", "ContextStartedEvent");
}
if (event instanceof ContextClosedEvent){
log.info("================:{}", "ContextClosedEvent");
}
if (event instanceof ContextStoppedEvent){
log.info("================:{}", "ContextStoppedEvent");
}
// 2. ServletWebServerInitializedEvent事件,在ApplicationContext完成刷新refreshed并启动tomcat容器后调用
if (event instanceof ServletWebServerInitializedEvent){
ServletWebServerApplicationContext applicationContext = ((ServletWebServerInitializedEvent) event).getApplicationContext();
String[] beanDefinitionNames = applicationContext.getBeanDefinitionNames();
for (String beanDefinitionName : beanDefinitionNames) {
log.info(beanDefinitionName);
}
log.info("================:{}", "ServletWebServerInitializedEvent");
}
if (event instanceof ApplicationReadyEvent){
log.info("================:{}", "ApplicationReadyEvent");
}
if (event instanceof ApplicationStartedEvent){
log.info("================:{}", "ApplicationStartedEvent");
}
log.info(">>>>>>>>>>>>>>>>:{}\n", event.getClass().getName());
}
}
- ContextRefreshedEvent事件 和 ServletWebServerInitializedEvent事件
1.首先,ContextRefreshedEvent通过继承ApplicationContextEvent,ApplicationContextEvent继承ApplicationEvent创建一个事件。
public class ContextRefreshedEvent extends ApplicationContextEvent {
public ContextRefreshedEvent(ApplicationContext source) {
super(source);
}
}
public abstract class ApplicationContextEvent extends ApplicationEvent {}
2.其次,发布一个监听器,如最上面的代码。
3.最后,发布事件。
this.refreshContext(context); //启动类里这里刷新容器 ->进入方法......
this.refresh(context);// -> 进入方法......
((AbstractApplicationContext)applicationContext).refresh(); // ->进入方法......
// 这个方法是创建tomcat容器
this.onRefresh();
this.registerListeners();
this.finishBeanFactoryInitialization(beanFactory);
// 这个方法里面主要发布ContextRefreshedEvent事件,启动tomcat容器并发布ServletWebServerInitializedEvent事件(即tomcat容器启动事件)
this.finishRefresh(); // -> 进入方法......
protected void finishRefresh() {
// 进入可看到this.publishEvent((ApplicationEvent)(new ContextRefreshedEvent(this)));即发布ContextRefreshedEvent事件
super.finishRefresh(); // -> 进入方法......
// 这个方法是启动tomcat容器
WebServer webServer = this.startWebServer();
if (webServer != null) {
// 发布ServletWebServerInitializedEvent事件,监听器就可以捕捉到并做处理了
this.publishEvent(new ServletWebServerInitializedEvent(webServer, this));
}
}
protected void finishRefresh() {
this.clearResourceCaches();
this.initLifecycleProcessor();
this.getLifecycleProcessor().onRefresh();
// 发布ContextRefreshedEvent事件,监听器就可以捕捉到并做处理了
this.publishEvent((ApplicationEvent)(new ContextRefreshedEvent(this)));
LiveBeansView.registerApplicationContext(this);
}
public ConfigurableApplicationContext run(String... args) {
// 省略无关紧要代码......
listeners.started(context); // 发布ApplicationStartedEvent事件,进入看源码道理一样
this.callRunners(context, applicationArguments);
} catch (Throwable var10) {
this.handleRunFailure(context, var10, exceptionReporters, listeners);
throw new IllegalStateException(var10);
}
try {
// 发布ApplicationReadyEvent事件,进入看源码道理一样
listeners.running(context);
return context;
} catch (Throwable var9) {
this.handleRunFailure(context, var9, exceptionReporters, (SpringApplicationRunListeners)null);
throw new IllegalStateException(var9);
}
}
备注:request,session等都可以通过监听器是实现业务逻辑,比如统计在线访问数量,浏览数等。自己也可以通过定义事件源和监听器的方式,在对象或者bean被处理的时候发布事件去进行业务处理。
网友评论