springboot源码----EventPublishingRunListener

EventPublishingRunListener 类实现了SpringApplicationRunListener接口,那么在springboot启动的过程中都会对这个类进行回调通知,那么通知什么? 其实看源码可以看出来里面对所有通知其实都是回调了ApplicationListener接口,说白了就是他就是一个ApplicationListener的代理。springboot启动的几个主要过程的监听通知都是通过他来进行回调

首先看下starting方法:

@Override
    public void starting() {
        this.initialMulticaster.multicastEvent(
                new ApplicationStartingEvent(this.application, this.args));
    }

第一步调用了SimpleApplicationEventMulticaster类的multicastEvent方法并且传入了ApplicationStartingEvent对象。

public void multicastEvent(final ApplicationEvent event, @Nullable ResolvableType eventType) {
        ResolvableType type = (eventType != null ? eventType : resolveDefaultEventType(event));
        for (final ApplicationListener listener : getApplicationListeners(event, type)) {
            Executor executor = getTaskExecutor();
            if (executor != null) {
                executor.execute(() -> invokeListener(listener, event));
            }
            else {
                invokeListener(listener, event);
            }
        }
    }

紧接着遍历了每个事件是ApplicationStartingEvent的监听器


    @SuppressWarnings({"unchecked", "rawtypes"})
    private void doInvokeListener(ApplicationListener listener, ApplicationEvent event) {
        try {
            listener.onApplicationEvent(event);
        }
        catch (ClassCastException ex) {
            String msg = ex.getMessage();
            if (msg == null || matchesClassCastMessage(msg, event.getClass().getName())) {
                // Possibly a lambda-defined listener which we could not resolve the generic event type for
                // -> let's suppress the exception and just log a debug message.
                Log logger = LogFactory.getLog(getClass());
                if (logger.isDebugEnabled()) {
                    logger.debug("Non-matching event type for listener: " + listener, ex);
                }
            }
            else {
                throw ex;
            }
        }
    }

最后进行回调

这边有几个问题:

  • EventPublishingRunListener是什么时候初始化的
  • SimpleApplicationEventMulticaster类里面的ApplicationListener实现类是怎么来的

EventPublishingRunListener初始化在前面一遍文章中已经介绍过
这边主要看下EventPublishingRunListener的构造器:

    public EventPublishingRunListener(SpringApplication application, String[] args) {
        this.application = application;
        this.args = args;
        this.initialMulticaster = new SimpleApplicationEventMulticaster();
        for (ApplicationListener listener : application.getListeners()) {
            this.initialMulticaster.addApplicationListener(listener);
        }
    }

这边可以看出来在EventPublishingRunListener初始化的时候会把SpringApplication带进来,而SpringApplication的对象中就有ApplicationListener的实现类 实在ApplicationListener初始化的时候生成的。

注意下contextLoaded方法

    @Override
    public void contextLoaded(ConfigurableApplicationContext context) {
        for (ApplicationListener listener : this.application.getListeners()) {
            if (listener instanceof ApplicationContextAware) {
                ((ApplicationContextAware) listener).setApplicationContext(context);
            }
            context.addApplicationListener(listener);
        }
        this.initialMulticaster.multicastEvent(
                new ApplicationPreparedEvent(this.application, this.args, context));
    }

这边这个方法比前面的方法特殊了一点,前面的方法直接调用this.initialMulticaster.multicastEvent就结束了。这边还做了另外两件事

  • 1 遍历了SpringApplication中所有的ApplicationListener实现类,如果有实现类还实现了ApplicationContextAware接口 就把上下文给其设置进去
  • 2 将这些 ApplicationListener实现类全部加入到上下文中(这个大家应该比较属性我们实现自己的监听的时候也会这么做)

这个方法是个分水岭 在这个方法之前的回到方法全部是通过SimpleApplicationEventMulticaster来进行回调
然后在这个之后的方法就全部通过context.publishEvent来进行回调

这也不难理解 因为只有到了contextLoaded方法之后才有了上下 之前还没有上下文所以只能通过SimpleApplicationEventMulticaster类进行回调所有的ApplicationListener实现类

你可能感兴趣的:(springboot源码----EventPublishingRunListener)