美文网首页
springboot监听器启动分析

springboot监听器启动分析

作者: 凌晨的咸鱼 | 来源:发表于2021-07-22 16:41 被阅读0次

    先上一段代码

    // 继承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监听器启动分析

          本文链接:https://www.haomeiwen.com/subject/lezemltx.html