zoukankan      html  css  js  c++  java
  • springIOC源码接口分析(七):ApplicationEventPublisher

    一 定义方法

    此接口主要是封装事件发布功能的接口,定义了两个方法:

        /**
         * 通知应用所有已注册且匹配的监听器此ApplicationEvent
         */
        default void publishEvent(ApplicationEvent event) {
            publishEvent((Object) event);
        }
    
        /**
         * 通知应用所有已注册且匹配的监听器此Event ,
         * 如果这个Event不是一个ApplicationEvent,则其被包裹于PayloadApplicationEvent
         */
        void publishEvent(Object event);

    二 ApplicationEvent 事件抽象类

       spring中ApplicationEvent +ApplicationListener 是观察者模式的一种实现。

    public abstract class ApplicationEvent extends EventObject {
    
        /** use serialVersionUID from Spring 1.2 for interoperability. */
        private static final long serialVersionUID = 7099057708183571937L;
    
        /** 事件发生的系统时间 */
        private final long timestamp;
    
    
        // 构造器
        public ApplicationEvent(Object source) {//发生事件的对象
            super(source);
            this.timestamp = System.currentTimeMillis();
        }
    
        public final long getTimestamp() {
            return this.timestamp;
        }
    }
    ApplicationEvent类继承了EventObject类 ,构造器中的source都是父类的不需要序列化的属性,添加了自身的事件发生时间的属性

     transient作用: https://www.cnblogs.com/chenpi/p/6185773.html

    三 spring内置事件

     spring里面有许多Event的实现,包括springBoot里面又新增了一些实现,下面是这些实现:

     ApplicationEvent的实现主要分为三条线:

     1 PayloadApplicationEvent,是可以使用泛型的事件,不用进行强转

     2 ApplicationContextEvent以及其四个子类

        ApplicationContextEvent是对应应用上下文的事件,主要有四个事件,分别是:

    • ContextRefreshedEvent  刷新

    • ContextClosedEvent  关闭

    • ContextStartedEvent  启动

    • ContextStoppedEvent  暂停

     3 RequestHandledEvent,对应http服务事件,其实现类定义了一些http请求有关的参数,url,状态code等:

    三 ApplicationListener 监听器接口

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

    ApplicationListener接口继承了EventListener 接口,java中所有的监听器都继承了这个接口猛兽jdk,util包下面的接口,接口接受ApplicationEvent的子类作为监听事件.
    使用监听器一般有两种方式:

      一 实现ApplicationListener接口

       比如spring内置的一个监听器:

      

     二 使用@EventListener注解的方式

      

    注册了监听器之后,发布对应事件就会通过事件处理器管理类多播到对应的监听逻辑,即onApplicationEvent方法

    四 ApplicationEventMulticaster 事件处理器管理类

      ApplicationEventMulticaster接口定义了7个管理监听器的方法,只有一个实现类SimpleApplicationEventMulticaster,方法分别是:

      

        /**
         * 添加监听器,用来接收所有事件的通知
         */
        void addApplicationListener(ApplicationListener<?> listener);
    
        /**
         * 根据Bean名称添加监听器
         */
        void addApplicationListenerBean(String listenerBeanName);
    
        /**
         * 移除监听器
         */
        void removeApplicationListener(ApplicationListener<?> listener);
    
        /**
         * 根据名称移除监听器
         */
        void removeApplicationListenerBean(String listenerBeanName);
    
        /**
         * 移除所有监听器
         */
        void removeAllListeners();
    
        /**
         * 将事件广播到对应的监听器中
         */
        void multicastEvent(ApplicationEvent event);
    
        /**
         * 将事件广播到对应的监听器中
         */
        void multicastEvent(ApplicationEvent event, @Nullable ResolvableType eventType);

    接下来看实现类中广播事件的方法:

        @Override
        public void multicastEvent(ApplicationEvent event) {
            multicastEvent(event, resolveDefaultEventType(event));//获取默认类型
        }
    
        @Override
        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);//调用对应的监听器逻辑方法
                }
            }
        }

    类中维护了一个Set,用来存放监听器,且监听事件都是异步线程池执行的.

  • 相关阅读:
    Chandy-Lamport_algorithm
    3 differences between Savepoints and Checkpoints in Apache Flink
    列数 行数 表数 限制
    数据收集、传输、元数据管理、作业流调度、海量数据查询引擎、数据可视化
    分析云负载均衡产品
    端口被占用通过域名的处理 把www.domain.com均衡到本机不同的端口 反向代理 隐藏端口 Nginx做非80端口转发 搭建nginx反向代理用做内网域名转发 location 规则
    JSON Web Token
    查看开启端口的应用
    If the parts of an organization (e.g., teams, departments, or subdivisions) do not closely reflect the essential parts of the product, or if the relationship between organizations do not reflect the r
    微服务架构的理论基础
  • 原文地址:https://www.cnblogs.com/houzheng/p/11885272.html
Copyright © 2011-2022 走看看