先上一段代碼
// 繼承ApplicationListener發(fā)布一個監(jiān)聽器售滤,并沒有指定范型(類似ApplicationListener< ContextRefreshedEvent >這樣只能監(jiān)聽ContextRefreshedEvent事件)
// 所以,所有的發(fā)布事件全都可以被監(jiān)聽到
@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創(chuàng)建一個事件屉更。
public class ContextRefreshedEvent extends ApplicationContextEvent {
public ContextRefreshedEvent(ApplicationContext source) {
super(source);
}
}
public abstract class ApplicationContextEvent extends ApplicationEvent {}
????2.其次,發(fā)布一個監(jiān)聽器毯侦,如最上面的代碼哭靖。
????3.最后,發(fā)布事件侈离。
this.refreshContext(context); //啟動類里這里刷新容器 ->進入方法......
this.refresh(context);// -> 進入方法......
((AbstractApplicationContext)applicationContext).refresh(); // ->進入方法......
// 這個方法是創(chuàng)建tomcat容器
this.onRefresh();
this.registerListeners();
this.finishBeanFactoryInitialization(beanFactory);
// 這個方法里面主要發(fā)布ContextRefreshedEvent事件试幽,啟動tomcat容器并發(fā)布ServletWebServerInitializedEvent事件(即tomcat容器啟動事件)
this.finishRefresh(); // -> 進入方法......
protected void finishRefresh() {
// 進入可看到this.publishEvent((ApplicationEvent)(new ContextRefreshedEvent(this)));即發(fā)布ContextRefreshedEvent事件
super.finishRefresh(); // -> 進入方法......
// 這個方法是啟動tomcat容器
WebServer webServer = this.startWebServer();
if (webServer != null) {
// 發(fā)布ServletWebServerInitializedEvent事件,監(jiān)聽器就可以捕捉到并做處理了
this.publishEvent(new ServletWebServerInitializedEvent(webServer, this));
}
}
protected void finishRefresh() {
this.clearResourceCaches();
this.initLifecycleProcessor();
this.getLifecycleProcessor().onRefresh();
// 發(fā)布ContextRefreshedEvent事件霍狰,監(jiān)聽器就可以捕捉到并做處理了
this.publishEvent((ApplicationEvent)(new ContextRefreshedEvent(this)));
LiveBeansView.registerApplicationContext(this);
}
public ConfigurableApplicationContext run(String... args) {
// 省略無關緊要代碼......
listeners.started(context); // 發(fā)布ApplicationStartedEvent事件抡草,進入看源碼道理一樣
this.callRunners(context, applicationArguments);
} catch (Throwable var10) {
this.handleRunFailure(context, var10, exceptionReporters, listeners);
throw new IllegalStateException(var10);
}
try {
// 發(fā)布ApplicationReadyEvent事件,進入看源碼道理一樣
listeners.running(context);
return context;
} catch (Throwable var9) {
this.handleRunFailure(context, var9, exceptionReporters, (SpringApplicationRunListeners)null);
throw new IllegalStateException(var9);
}
}
備注:request蔗坯,session等都可以通過監(jiān)聽器是實現(xiàn)業(yè)務邏輯康震,比如統(tǒng)計在線訪問數(shù)量,瀏覽數(shù)等宾濒。自己也可以通過定義事件源和監(jiān)聽器的方式腿短,在對象或者bean被處理的時候發(fā)布事件去進行業(yè)務處理。