springboot监听器启动分析

先上一段代码

// 继承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被处理的时候发布事件去进行业务处理。

你可能感兴趣的:(springboot监听器启动分析)