zoukankan      html  css  js  c++  java
  • Spring Event

    Spring Event 是基于观察者模式实现,介绍其之前,我们先介绍下JDK提供的观察者模型

    观察者:Observer,

     

    被观察:Observable

     

    当被观察者改变时,其需要通知所有关联的观察者。Observable实现逻辑如下:

    1、 Observable定义了一个数据结构:Vector<Observer>,记录关联的Observer。
    2、 通知关联的观察者:调用方法notifyObservers(调用所有Observer的update方法)。

    好了,下面我们介绍Spring基于观察者模式的Event机制

    首先介绍Spring Event的关键的类

    1、 ApplicationEvent 事件

    2、 ApplicationListener 监听(Observer)

    3、 ApplicationEventPublisher 发布(Observable)

    整体逻辑如下:

    ApplicationEventPublisher发布ApplicationEvent给关联的ApplicationListener。

    根据观察者模式,我们可以推导出来:

           ApplicationEventPublisher持有关联的ApplicationListener列表,调用ApplicationListener的方法(将ApplicationEvent作为入参传入过去),达到通知的效果。但问题来了,ApplicationEventPublisher如何知道这个ApplicationListener发给哪个ApplicationListener呢?

    下面我们一步一步解析。

    ApplicationListener(Observer)

     

    ApplicationEventPublisher(Observable)

    正在实现ApplicationEventPublisher.publishEvent这个方法的有两个类

    有两个类AbstractApplicationContext和它的子类SimpleApplicationEventMulticaster

     

    AbstractApplicationContext功能是存放所有关联的ApplicationListener。数据结构如下:

    Map<ListenerCacheKey, ListenerRetriever> retrieverCache。

    ListenerCacheKey构成:

    1、ResolvableType eventType(对应的是ApplicationEvent)

    2、Class<?> sourceType(对应的是EventObject)

    ListenerRetriever构成:

    1、 Set<ApplicationListener<?>> applicationListeners(监听)

    答案很显然,ApplicationEventPublisher是通过ApplicationEvent(继承ApplicationEvent的Class类)类型来关联需要调用的ApplicationListener。

     SimpleApplicationEventMulticaster的功能是:多线程调用所有关联的ApplicationListener的onApplicationEvent方法的。

    实践:

    创建Event

    public class Event extends ApplicationEvent {
        private String message;
        public Event(Object source, String message) {
            super(source);
            this.message = message;
        }
        public String getMessage() {
            return message;
        }
    }

    创建监听:

    1、实现ApplicationListener
    @Component
    public class ImplementsListener implements ApplicationListener<Event> {
        @Override
        public void onApplicationEvent(Event event) {
            //TODO
        }
    }
    2、加@EventListener注解
    @Component
    public class AnnotationListener {
        @EventListener
        public void eventListener(Event event) {
            //TODO
        }
    }

    事件发布:

    @Component
    public class EventPublisher {
        @Autowired
        private ApplicationEventPublisher applicationEventPublisher;
        public void publish() {
            applicationEventPublisher.publishEvent(new Event(this, "it's demo"));
        }
    }

    自定义事件广播:

    @Component(APPLICATION_EVENT_MULTICASTER_BEAN_NAME)
    public class CustomApplicationEventMulticaster extends AbstractApplicationEventMulticaster {
        @Override public void multicastEvent(ApplicationEvent event) {
            //TODO custom invokeListener(listener, event);
        }
        @Override public void multicastEvent(ApplicationEvent event, ResolvableType eventType) {
            //TODO custom invokeListener(listener, event);
        }
    }
  • 相关阅读:
    全排列和几道例题
    NOJ1333: [蓝桥杯2017初赛]Excel地址
    力扣5-最长回文子串-(Manacher算法)
    CF1003E-Tree Constructing-(构造+dfs)
    NOJ1329:[蓝桥杯2017初赛]k倍区间-(前缀和)
    Java 时间
    小魂和他的数列-(离散+二分+树状数组)
    AC自动机入门和几道例题
    java写入加速
    清理 Excel 导出的 HTML 的多余属性
  • 原文地址:https://www.cnblogs.com/sleepingDogs/p/11070918.html
Copyright © 2011-2022 走看看