• Spring ApplicationListener进阶版


    上一篇文章,属于基础版ApplicationListener基础版,我们正常的业务使用,但是还有一些缺陷:

    1. 同一个数据的增删改,需要建立对应的操作事件。
    2. 没有提取公共部分,例如:Listener的互相影响问题,存在一个Listener出现异常,影响其他Listener的消费。

    ApplicationListener进阶版

    数据抽象

    public class BaseSource implements Serializable {
    
        private String sourceType;
    
        public BaseSource(String sourceType) {
            this.sourceType = sourceType;
        }
    
        /**
         * 数据类型
         * 监听者根据类型,进行判断是否处理。
         * 类似MQ中的tag
         *
         * @return 数据类型
         */
        public String getSourceType() {
            return sourceType;
        }
    
        public boolean isDeleteOperate() {
            return EventSourceOperation.DELETE.getOperate().equals(getSourceType());
        }
    
        public boolean isAddOperate() {
            return EventSourceOperation.ADD.getOperate().equals(getSourceType());
        }
    
        public boolean isEditOperate() {
            return EventSourceOperation.EDIT.getOperate().equals(getSourceType());
        }
    
    
    }
    
    
    /**操作类型枚举*/
    public enum EventSourceOperation {
        ADD("ADD", "新增"),
        EDIT("EDIT", "修改"),
        DELETE("DELETE", "删除");
        private final String operate;
        private final String desc;
    
        EventSourceOperation(String operate, String desc) {
            this.operate = operate;
            this.desc = desc;
        }
    
        public String getOperate() {
            return operate;
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52

    事件抽象

    抽象出BaseEvent,主要作用:

    1. 添加业务属性name。
    2. 解决ApplicationEvent获取Source时,返回Object,通过泛型解决Listener的类型转换。
    public class BaseEvent<S extends BaseSource> extends ApplicationEvent {
        private String name;
    
        public BaseEvent(S s) {
            this("", s);
        }
    
        public BaseEvent(String name, S s) {
            super(s);
            this.name = name;
    
        }
    
        @Override
        public S getSource() {
            return (S) super.getSource();
        }
    
        public String getName() {
            return name;
        }
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23

    监听抽象

    接口抽象

    抽取公共接口,规定了监听需要具有的通用接口,让监听更完善。

    public interface IEventListener<E extends BaseEvent> extends ApplicationListener<E> {
    
        /**
         * 是否支持,根据需要判断是否进行下一步
         *
         * @param event 事件
         * @return true=支持
         */
        boolean support(E event);
    
    
        /**
         * 处理事件,建议自行try catch
         *
         * @param event 事件
         */
        void handleEvent(E event);
    
        /**
         * 处理异常,如果没有try catch,会自动捕捉并包装异常
         *
         * @param event                事件
         * @param eventHandleException 事件处理过程中,出现的异常
         */
        void handleException(E event, EventHandleException eventHandleException);
    
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27

    基础实现

    基础监听,实现IEventListener,同时对事件与数据进行剥离,原因:监听器,其实核心关心的是事件带有的数据,因此提供:BaseEventSourceListener,监听只需要关心Source即可。类似于:MQ消息,关心的不是消息,而是消息承载的内容。

    public abstract class BaseEventSourceListener<E extends BaseEvent<S>, S extends BaseSource> implements IEventListener<E> {
        @Override
        public boolean support(E event) {
            return supportSource(event.getSource());
        }
    
        /**
         * 子类重写,是否支持事件中的数据,
         * 类似于:MQ中的tag判断,通过一个事件,承载不同处理的数据。
         *
         * @param source 数据
         * @return true=支持该数据
         */
        public abstract boolean supportSource(S source);
    
    
        @Override
        public void handleEvent(E event) {
            handleSource(event.getSource());
        }
    
        /**
         * 处理该事件的核心数据
         *
         * @param source 事件的核心:数据
         */
        public abstract void handleSource(S source);
    
    	/**
         * 默认处理方式:
         * 包装异常,同时抛出特殊异常
         * */
        @Override
        public void handleException(E event, EventHandleException eventHandleException) {
            throw eventHandleException;
        }
    
        @Override
        public void onApplicationEvent(E event) {
            if (support(event)) {
            	//try catch的必要性,当多个Listener监听同一个事件时,防止监听之间的互相影响 
                try {
                    handleEvent(event);
                } catch (Exception e) {
                    handleException(event, new EventHandleException(e));
                }
            }
        }
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50

    示例监听

    用户新增的监听

    public class UserAddChangeListener extends BaseEventSourceListener<UserChangeEvent, UserChange> {
        @Override
        public boolean supportSource(UserChange source) {
            return source.isAddOperate();
        }
    
        @Override
        public void handleSource(UserChange source) {
            System.out.println("user change add:" + source.toString());
        }
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12

    用户删除的监听

    public class UserDeleteChangeListener extends BaseEventSourceListener<UserChangeEvent, UserChange> {
        @Override
        public boolean supportSource(UserChange source) {
            return source.isDeleteOperate();
        }
    
        @Override
        public void handleSource(UserChange source) {
            System.out.println("user change delete:" + source.toString());
        }
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12

    发布事件

    
    public static void main(String[] args) throws InterruptedException {
            AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext();
    applicationContext.register(UserAddChangeListener.class);
            applicationContext.register(UserDeleteChangeListener.class);
            applicationContext.refresh();
    
            applicationContext.publishEvent(new UserChangeEvent(UserChange.createAddOperation(1, "userAdd ")));
            applicationContext.publishEvent(new UserChangeEvent(UserChange.createDeleteOperation(1, "userDelete ")));
        }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11

    结果输出

    user change add:UserChange(id=1, name=userAdd )
    user change delete:UserChange(id=1, name=userDelete )

    源码版

    Spring ApplicationListener源码版

  • 相关阅读:
    【英语考研词汇训练营】Day 15 —— analyst,general,avoid,surveillance,compared
    Ubuntu记录
    EL表达式的内置对象及其作用域
    Salesforce-Visualforce-6.静态资源(Static Resources)
    Python 打印文本进度条
    汇编语言之栈
    CTF竞赛题解之stm32逆向入门
    如何打开不同格式的图片?图片格式转换的方法又有哪些?
    03.大型高并发微服务系统设计
    文举论金:非农到来!黄金原油全面走势分析策略独家指导
  • 原文地址:https://blog.csdn.net/u010652576/article/details/126214180