美文网首页
Spring的事件驱动模型

Spring的事件驱动模型

作者: 码而优则仕 | 来源:发表于2020-06-30 22:46 被阅读0次

    Spring的事件驱动模型

    事件驱动模型的三大组成部分

    • 事件:ApplicationEvent 抽象类—继承自 JDK 的 EventObject
    public abstract class ApplicationEvent extends EventObject {
    
       /** use serialVersionUID from Spring 1.2 for interoperability. */
       private static final long serialVersionUID = 7099057708183571937L;
    
       /** System time when the event happened. */
       private final long timestamp;
    
    
       /**
        * Create a new {@code ApplicationEvent}.
        * @param source the object on which the event initially occurred or with
        * which the event is associated (never {@code null})
        */
       public ApplicationEvent(Object source) {
          super(source);
          this.timestamp = System.currentTimeMillis();
       }
    
    
       /**
        * Return the system time in milliseconds when the event occurred.
        */
       public final long getTimestamp() {
          return this.timestamp;
       }
    
    }
    

    所有事件将继承于 ApplicationEvent,并通过继承自EventObject 的成员变量 source 获取到事件源 (注册事件监听器和发布事件的地方) ;Spring中 事件源 一般是容器本身。
    如:ApplicationContextEvent(也是一个抽象的事件)--容器事件

    public abstract class ApplicationContextEvent extends ApplicationEvent {
    
       /**
        * Create a new ContextStartedEvent.
        * @param source the {@code ApplicationContext} that the event is raised for
        * (must not be {@code null})
        */
       public ApplicationContextEvent(ApplicationContext source) {
          super(source);
       }
    
       /**
        * Get the {@code ApplicationContext} that the event was raised for.
        */
       public final ApplicationContext getApplicationContext() {
          return (ApplicationContext) getSource();
       }
    
    }
    

    具体容器事件有:
    ContextStartedEvent,ContextStopedEvent,ContextClosedEvent,ContextRefreshedEvent
    PayloadApplicationEvent—Spring 4.2之后框架提供的 ApplicationEvent 的子类由于是泛型类,所以可以用来包装任何事件;在容器内部发送的任意类型的事件都会被包装成为 PayloadApplicationEvent 事件对象;包括前面介绍的四个具体 容器事件类

    public class PayloadApplicationEvent<T> extends ApplicationEvent implements ResolvableTypeProvider {
    
     private final T payload;
    
    
     /**
      * Create a new PayloadApplicationEvent.
      * @param source the object on which the event initially occurred (never {@code null})
      * @param payload the payload object (never {@code null})
      */
     public PayloadApplicationEvent(Object source, T payload) {
        super(source);
        Assert.notNull(payload, "Payload must not be null");
        this.payload = payload;
     }
    
    
     @Override
     public ResolvableType getResolvableType() {
        return ResolvableType.forClassWithGenerics(getClass(), ResolvableType.forInstance(getPayload()));
     }
    
     /**
      * Return the payload of the event.
      */
     public T getPayload() {
        return this.payload;
     }
    
    }
    
    事件监听器(ApplicationListener)— 继承自 JDK 的 EventListener

    JDK 要求所有的监听器都要继承这个 EventListener

    @FunctionalInterface
    public interface ApplicationListener<E extends ApplicationEvent> extends EventListener {
    
       /**
        * Handle an application event.
        * @param event the event to respond to
        */
       void onApplicationEvent(E event);
    
    }
    

    Spring 中 定义了 ApplicationListener 的两个自接口:SmartApplicationListener,

    //实现 Ordered 接口 支持排序功能 ,对监听器进行排序
    public interface SmartApplicationListener extends ApplicationListener<ApplicationEvent>, Ordered {
    
        /**
         * Determine whether this listener actually supports the given event type.
         * @param eventType the event type (never {@code null})
         * 判断事件类型 是否和当前 监听者匹配--基于这个方法 筛选监听者感兴趣的事件
         */
        boolean supportsEventType(Class<? extends ApplicationEvent> eventType);
    
        /**
         * Determine whether this listener actually supports the given source type.
         * <p>The default implementation always returns {@code true}.
         * @param sourceType the source type, or {@code null} if no source
         * 判断事件源类型 是否和当前 监听者匹配 -- 基于这个方法 筛选监听者感兴趣的事件源
         */
        default boolean supportsSourceType(@Nullable Class<?> sourceType) {
            return true;
        }
    
        /**
         * Determine this listener's order in a set of listeners for the same event.
         * <p>The default implementation returns {@link #LOWEST_PRECEDENCE}.
         */
        @Override
        default int getOrder() {
            return LOWEST_PRECEDENCE;
        }
    
    }
    
    public interface GenericApplicationListener extends ApplicationListener<ApplicationEvent>, Ordered {
    
       /**
        * Determine whether this listener actually supports the given event type.
        * @param eventType the event type (never {@code null})
        * 判断事件类型 是否和当前 监听者匹配--基于这个方法 筛选监听者感兴趣的事件
        *  事件类型 ResolvableType
        *   是Spring 4 之后添加的 获取泛型信息的工具,通过这个工具类可以获取到传入的 泛型的各种信息
        */
       boolean supportsEventType(ResolvableType eventType);
    
       /**
        * Determine whether this listener actually supports the given source type.
        * <p>The default implementation always returns {@code true}.
        * @param sourceType the source type, or {@code null} if no source
        * 判断事件源类型 是否和当前 监听者匹配 -- 基于这个方法 筛选监听者感兴趣的事件源
        */
       default boolean supportsSourceType(@Nullable Class<?> sourceType) {
          return true;
       }
    
       /**
        * Determine this listener's order in a set of listeners for the same event.
        * <p>The default implementation returns {@link #LOWEST_PRECEDENCE}.
        */
       @Override
       default int getOrder() {
          return LOWEST_PRECEDENCE;
       }
    
    }
    
    • 用户可以实现 ApplicationListener 接口 实现方法 onApplicationEvent 来自定义自己的 事件监听器 。也可以使用注解@EventListener 在想 成为监听器的 Bean 监听方法上加上该注解
    • 事件发布器(ApplicationEventPublisher和 ApplicationEventMulticaster)容器接口继承自这几个接口,就具备了发布事件的能力。ApplicationEventPublisher 这个接口只定义了发布事件的方法,但是事件监听器的注册等方法没有,而ApplicationEventMulticaster 里面所有方法都有,AbstractApplicationEventMulticaster 抽象类实现了 ApplicationEventMulticaster 接口的所有方法的抽象类,具体实现类是 SimpleApplicationEventMulticaster
      ApplicationEventPublisher定义的事件发布方法,实现类最后都是调用的ApplicationEventMulticaster接口定义的事件发布方法—拆分成两个接口是由于容器只关心事件发布,所以实现这个接口就可以了,具体实现是调ApplicationEventMulticaster接口的实现类完成的


      UML.png
    public interface ApplicationContext extends EnvironmentCapable, ListableBeanFactory, HierarchicalBeanFactory,
          MessageSource, ApplicationEventPublisher, ResourcePatternResolver {
    
    public interface ApplicationEventPublisherAware extends Aware {
    
       /**
        * Set the ApplicationEventPublisher that this object runs in.
        * <p>Invoked after population of normal bean properties but before an init
        * callback like InitializingBean's afterPropertiesSet or a custom init-method.
        * Invoked before ApplicationContextAware's setApplicationContext.
        * @param applicationEventPublisher event publisher to be used by this object
        */
       void setApplicationEventPublisher(ApplicationEventPublisher applicationEventPublisher);
    
    }
    

    Bean 可以 通过上面的 ApplicationEventPublisherAware 获取到 ApplicationEventPublisher实例--其实也就是获取到容器这个实例,就可以发布自定义的事件,给容器里面自定义的 EventListener

    相关文章

      网友评论

          本文标题:Spring的事件驱动模型

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