zoukankan      html  css  js  c++  java
  • Spring的事件驱动机制

    声明:本文摘抄自:https://blog.csdn.net/uk8692/article/details/105874972/?utm_medium=distribute.pc_relevant.none-task-blog-2~default~baidujs_baidulandingword~default-0.control&spm=1001.2101.3001.4242

    观察者模式
    前面有聊过设计模式中的观察者模式,想必大家都应该有所耳闻。这里我们大致回顾一下,观察者模式中有几个角色:
    主题:主题中包含多个观察者,以及观察者的添加、删除,同时需要提供触发观察者事件的方法。
    观察者:也叫监听器,会有多个观察者,不同的观察者监听到事件后做不同的逻辑处理。
    实现自己的事件驱动机制

    在spring中有很多事件监听,其实它们的思想是观察者模式。常见的事件监听机制的主要角色如下:

    事件及事件源:对应于观察者模式中的主题。事件源发生某事件是特定事件监听器被触发的原因。
    事件监听器:对应于观察者模式中的观察者。监听器监听特定事件,并在内部定义了事件发生后的响应逻辑。
    事件发布器:事件监听器的容器,对外提供发布事件和增删事件监听器的接口,维护事件和事件监听器之间的映射关系,并在事件发生时负责通知相关监听器。

    Spring框架对事件的发布与监听提供了相对完整的支持,它扩展了JDK中对自定义事件监听提供的基础框架,并与Spring的IOC特性作了整合,使得用户可以根据自己的业务特点进行相关的自定义,并依托Spring容器方便的实现监听器的注册和事件的发布。因为Spring的事件监听依托于JDK提供的底层支持,为了更好的理解,先来看下JDK中为用户实现自定义事件监听提供的基础框架。

    那么我们这里,举一个例子来自定义一下我们的事件监听:
    在电商项目中,用户下单成功后,需要进行短信、邮件通知,那么这里我们可以用事件监听来处理。
    Event:事件的接口类,可以设置或获取数据EventObject

    public interface Event extends Serializable {
        EventObject getEventObject();
        void setEventObject(EventObject eventObject);
    }

    AbstractEvent:事件抽象实现类,持有EventObject对象,并提供默认实现

    public abstract class AbstractEvent implements Event {
    
        private EventObject eventObject;
    
        public AbstractEvent(EventObject eventObject){
            this.eventObject = eventObject;
        }
    
        @Override
        public EventObject getEventObject() {
            return this.eventObject;
        }
    
        @Override
        public void setEventObject(EventObject eventObject) {
            this.eventObject = eventObject;
        }
    }

    OrderCallbackEvent:订单回调事件,用于定义具体的事件

    /**
     * 订单回调事件
     */
    public class OrderCallbackEvent extends AbstractEvent {
    
        public OrderCallbackEvent(EventObject eventObject) {
            super(eventObject);
        }
    }

    接着我们来定义事件的监听器(观察者),以及事件的广播器(主题)。

    EventListener:监听器接口类,定义监听器的方法

    public interface EventListener {
    
        void onEvent(Event event);
    }

    AbstractEventListener:监听器抽象实现类,这里多了order属性,用于监听器执行顺序

    public abstract class AbstractEventListener implements EventListener{
    
        private int order;
    
        public int getOrder() {
            return order;
        }
    
        public AbstractEventListener(int order){
            this.order = order;
        }
    
        @Override
        public void onEvent(Event event) {
        }
    }

    SmsEventListener:短信事件监听

    public class SmsEventListener extends AbstractEventListener {
    
        public SmsEventListener(int order) {
            super(order);
        }
    
        @Override
        public void onEvent(Event event) {
            System.out.println("短信事件监听>>>>>>>>>>>>>>>>>>>");
            EventObject eventObject = event.getEventObject();
            System.out.println(eventObject.toString());
    
        }
    }

    EmailEventListener:邮件事件监听

    public class EmailEventListener extends AbstractEventListener {
    
        public EmailEventListener(int order) {
            super(order);
        }
    
        @Override
        public void onEvent(Event event) {
            System.out.println("邮件事件监听>>>>>>>>>>>>>>>>>>>>>>>");
            EventObject eventObject = event.getEventObject();
            System.out.println(eventObject.toString());
        }
    }

    EventMulticaster:事件广播器

    public class EventMulticaster {
    
        private List<AbstractEventListener> listeners;
    
        public EventMulticaster(List<AbstractEventListener> listeners){
            this.listeners = listeners;
        }
    
        public void multicastEvent(Event event){
            //按照设置的顺序执行监听器
            for (EventListener listener : listeners) {
                listener.onEvent(event);
            }
        }
    }

    接着我们来测试一下,看广播器是如何发送事件的:

    public class TestEventListener {
    
        public static void main(String[] args) {
            List<AbstractEventListener> listeners = new ArrayList<>(2);
            listeners.add(new SmsEventListener(2));
            listeners.add(new EmailEventListener(1));
    
            listeners = listeners.stream()
                    .sorted(Comparator.comparing(AbstractEventListener::getOrder))
                    .collect(Collectors.toList());
    
            //定义广播器
            EventMulticaster eventMulticaster = new EventMulticaster(listeners);
    
            EventObject eventObject = new EventObject("Test"+System.currentTimeMillis());
            eventMulticaster.multicastEvent(new OrderCallbackEvent(eventObject));
        }
    }

    执行结果:
    邮件事件监听>>>>>>>>>>>>>>>>>>>>>>>
    java.util.EventObject[source=Test1588302935088]
    短信事件监听>>>>>>>>>>>>>>>>>>>
    java.util.EventObject[source=Test1588302935088]

    通过结果可以看到,我们定义的监听者都收到了广播发送的事件,同时也保证了接收的顺序。
    这里我们也可以针对每一个监听器开启一个独立的线程异步去执行监听业务,而不会阻塞回调事件的执行。

  • 相关阅读:
    基于RSA的WEB前端密码加密方案
    私钥加密公钥解密或者公钥加密私钥解密有意义吗?
    MySQL索引背后的数据结构及算法原理
    深入理解MySQL索引原理和实现——为什么索引可以加速查询?
    shim和polyfill有什么区别
    [转]使用HttpOnly提升Cookie安全性
    RLE压缩算法详解
    [转]详解布隆过滤器的原理,使用场景和注意事项
    小白科普:Netty有什么用?
    RSA的公钥和私钥到底哪个才是用来加密和哪个用来解密?
  • 原文地址:https://www.cnblogs.com/wk-missQ1/p/15074256.html
Copyright © 2011-2022 走看看