springboot源码剖析(二) 事件发布

  概念

           springboot在启动流程中会发布一些事件通知依赖组件进行主动更新。

           原理是springboot使用到的一种设计模式: 观察者模式。优点是解耦合启动流程,增加了spring的扩展性。


  实现原理

     被观察者会维护一个事件发布器,事件发布器会注册持有监听者(观察者)的引用。

          当被观察者发生状态改变,事件发布器会广播给所有对该事件感兴趣的监听者,之后监听者会执行对应的事件触发方法。

   uml类图

     事件发布流程


       源码剖析

           事件发布触发

/** springApplication.class 事件发布 */
public ConfigurableApplicationContext run(String... args) {
     ...
     // 扫描META-INF/spring-factories 中的org.springframework.boot.SpringApplicationRunListener,构造事件发布器
     SpringApplicationRunListeners listeners = this.getRunListeners(args);
     // ★ 给关注ApplicationStartingEvent事件的listenter发布消息
     listeners.starting();
     ...
 }

/** EventPublishingRunListener.class 事件发布器 */
// 构造方法(实现的观察者模式:由被观察者维护监听者并广播消息)
public EventPublishingRunListener(SpringApplication application, String[] args) {
    this.application = application;
    this.args = args;
    // ★ 实例化一个广播器
    this.initialMulticaster = new SimpleApplicationEventMulticaster();
    Iterator var3 = application.getListeners().iterator();
    // ★ 把springapplication类的监听器都注册到广播器中
    while(var3.hasNext()) {
        ApplicationListener<?> listener = (ApplicationListener)var3.next();
        this.initialMulticaster.addApplicationListener(listener);
    }
}
// 发布ApplicationStartingEvent事件
public void starting() {
    // 广播事件
    this.initialMulticaster.multicastEvent(new ApplicationStartingEvent(this.application, this.args));
}

              广播事件

/** SimpleApplicationEventMulticaster.class 广播器 */
// 广播事件
public void multicastEvent(ApplicationEvent event, @Nullable ResolvableType eventType) {
    ResolvableType type = eventType != null ? eventType : this.resolveDefaultEventType(event);
    // 多线程执行监听器更新
    Executor executor = this.getTaskExecutor();
    // 1.获取需要更新的监听器
    Iterator var5 = this.getApplicationListeners(event, type).iterator();

    // 2.执行监听器的更新
    while(var5.hasNext()) {
        ApplicationListener<?> listener = (ApplicationListener)var5.next();
        if (executor != null) {
            executor.execute(() -> {
                this.invokeListener(listener, event);
            });
        } else {
            // 最底层其实就是执行listener实现的onApplicationEvent(event)方法
            this.invokeListener(listener, event);
        }
    }
}
// 1.获取监听器
protected Collection<ApplicationListener<?>> getApplicationListeners(ApplicationEvent event, ResolvableType eventType) {
    // sprinApplication对象和类
    Object source = event.getSource();
    Class<?> sourceType = source != null ? source.getClass() : null;
    // cacheKey记录当前事件和事件类型
    AbstractApplicationEventMulticaster.ListenerCacheKey cacheKey = new AbstractApplicationEventMulticaster.ListenerCacheKey(eventType, sourceType);
    // retriever记录对应事件需要更新的监听器
    AbstractApplicationEventMulticaster.ListenerRetriever retriever = (AbstractApplicationEventMulticaster.ListenerRetriever)this.retrieverCache.get(cacheKey);
    if (retriever != null) {
        return retriever.getApplicationListeners();
    } else if (this.beanClassLoader == null || ClassUtils.isCacheSafe(event.getClass(), this.beanClassLoader) && (sourceType == null || ClassUtils.isCacheSafe(sourceType, this.beanClassLoader))) {
        synchronized(this.retrievalMutex) {
            retriever = (AbstractApplicationEventMulticaster.ListenerRetriever)this.retrieverCache.get(cacheKey);
            if (retriever != null) {
                return retriever.getApplicationListeners();
            } else {
                retriever = new AbstractApplicationEventMulticaster.ListenerRetriever(true);
                // 1.1 筛选对事件感兴趣的监听者
                Collection<ApplicationListener<?>> listeners = this.retrieveApplicationListeners(eventType, sourceType, retriever);
                this.retrieverCache.put(cacheKey, retriever);
                return listeners;
            }
        }
    } else {
        return this.retrieveApplicationListeners(eventType, sourceType, (AbstractApplicationEventMulticaster.ListenerRetriever)null);
    }
}
// 1.1 筛选监听者
private Collection<ApplicationListener<?>> retrieveApplicationListeners(ResolvableType eventType, @Nullable Class<?> sourceType, @Nullable AbstractApplicationEventMulticaster.ListenerRetriever retriever) {
    List<ApplicationListener<?>> allListeners = new ArrayList();
    LinkedHashSet listeners;
    LinkedHashSet listenerBeans;
    // 监听器数组
    synchronized(this.retrievalMutex) {
        listeners = new LinkedHashSet(this.defaultRetriever.applicationListeners);
        listenerBeans = new LinkedHashSet(this.defaultRetriever.applicationListenerBeans);
    }

    Iterator var7 = listeners.iterator();
    // 1.1.1 感兴趣的放入retriever数组中
    while(var7.hasNext()) {
        ApplicationListener<?> listener = (ApplicationListener)var7.next();
        if (this.supportsEvent(listener, eventType, sourceType)) {
            if (retriever != null) {
                retriever.applicationListeners.add(listener);
            }
            allListeners.add(listener);
        }
    }

    // 我运行的时候没有走到,多加了单例相关的判断
    if (!listenerBeans.isEmpty()) {
        /* ... */
    }

    // 排序,更新retriever的监听者
    AnnotationAwareOrderComparator.sort(allListeners);
    if (retriever != null && retriever.applicationListenerBeans.isEmpty()) {
        retriever.applicationListeners.clear();
        retriever.applicationListeners.addAll(allListeners);
    }    

    return allListeners;
}
// 1.1.1 监听器是否对事件感兴趣
protected boolean supportsEvent(ApplicationListener<?> listener, ResolvableType eventType, @Nullable Class<?> sourceType) {
    // 转成通用监听类型
    GenericApplicationListener smartListener = listener instanceof GenericApplicationListener ? (GenericApplicationListener)listener : new GenericApplicationListenerAdapter(listener);
    // 看监听器自己实现的supportsEventType和supportsSourceType方法是否对该事件感兴趣
    return ((GenericApplicationListener)smartListener).supportsEventType(eventType) && ((GenericApplicationListener)smartListener).supportsSourceType(sourceType);
}

           

posted @ 2022-10-30 15:08  Duikerdd  阅读(160)  评论(0编辑  收藏  举报