zoukankan      html  css  js  c++  java
  • spring之自定义事件及监听 原理

    上一节说了自定义事件及监听的实现,这一节说下他的实现原理。

    首先他发布事件使用过ApplicationContext.publishEvent()方法来实现,通过追踪发现publishEvent()方法的实现是在AbstractApplicationContext抽象类中实现。

    先捋请这几个类的具体继承和接口实现的层级关系。

    eclipse下的:

     

    然后再看AbstractApplicationContext下的publishEvent方法:

     1     /**
     2      * Publish the given event to all listeners.
     3      * @param event the event to publish (may be an {@link ApplicationEvent}
     4      * or a payload object to be turned into a {@link PayloadApplicationEvent})
     5      * @param eventType the resolved event type, if known
     6      * @since 4.2
     7      */
     8     protected void publishEvent(Object event, @Nullable ResolvableType eventType) {
     9         Assert.notNull(event, "Event must not be null");
    10 
    11         // Decorate event as an ApplicationEvent if necessary
    12         ApplicationEvent applicationEvent;
    13         if (event instanceof ApplicationEvent) {
    14             applicationEvent = (ApplicationEvent) event;
    15         }
    16         else {
    17             applicationEvent = new PayloadApplicationEvent<>(this, event);
    18             if (eventType == null) {
    19                 eventType = ((PayloadApplicationEvent<?>) applicationEvent).getResolvableType();
    20             }
    21         }
    22 
    23         // Multicast right now if possible - or lazily once the multicaster is initialized
    24         if (this.earlyApplicationEvents != null) {
    25             this.earlyApplicationEvents.add(applicationEvent);
    26         }
    27         else {
    // SimpleApplicationEventMulticaster 获取事件发布器,发布事件
    28 getApplicationEventMulticaster().multicastEvent(applicationEvent, eventType); 29 } 30 31 // Publish event via parent context as well... 32 if (this.parent != null) { 33 if (this.parent instanceof AbstractApplicationContext) { 34 ((AbstractApplicationContext) this.parent).publishEvent(event, eventType); 35 } 36 else { 37 this.parent.publishEvent(event); 38 } 39 } 40 }
    getApplicationEventMulticaster()代码:
     1 /**
     2      * Return the internal ApplicationEventMulticaster used by the context.
     3      * @return the internal ApplicationEventMulticaster (never {@code null})
     4      * @throws IllegalStateException if the context has not been initialized yet
     5      */
     6     ApplicationEventMulticaster getApplicationEventMulticaster() throws IllegalStateException {
     7         if (this.applicationEventMulticaster == null) {
     8             throw new IllegalStateException("ApplicationEventMulticaster not initialized - " +
     9                     "call 'refresh' before multicasting events via the context: " + this);
    10         }
    11         return this.applicationEventMulticaster;
    12     }
    ApplicationEventMulticaster 的multicastEvent()方法是在SimpleApplicationEventMulticaster类中实现。下面是层级结构图。

    SimpleApplicationEventMulticaster.multicastEvent()代码
     1     @Override
     2     public void multicastEvent(final ApplicationEvent event, @Nullable ResolvableType eventType) {
     3         ResolvableType type = (eventType != null ? eventType : resolveDefaultEventType(event));
    // getApplicationListeners(event, type) 筛选监听器,在context.publish(ApplicationEvent event)中已经将事件传入,getApplicationListeners中将可以根据这个event类型从Spring容器中检索出符合条件的监听器
    4 Executor executor = getTaskExecutor(); 5 for (ApplicationListener<?> listener : getApplicationListeners(event, type)) { 6 if (executor != null) { 7 executor.execute(() -> invokeListener(listener, event)); 8 } 9 else {
    10 invokeListener(listener, event);//尝试逐个向监听器广播 11 } 12 } 13 }

    下面是进行debug的结果:

          

    在multicastEvent发布完,就直接循环event事件
  • 相关阅读:
    [转]进程的用户栈和内核栈
    什么是URL,URL格式
    设计灵感
    Spring源码学习相关记录
    HTML图片标签路径解析
    一次Spring Bean初始化顺序问题排查记录
    是要面向对象,还是简单粗暴?
    2018/07/26学习节点记录
    数据结构-堆 Java实现
    2018 ICPC 徐州邀请赛 总结
  • 原文地址:https://www.cnblogs.com/swfzzz/p/12036239.html
Copyright © 2011-2022 走看看