• 4 Spring ApplicationListener 问题版


    为什么监听器不起作用

    先说场景:事件的数据源通过泛型进行抽象,通过不同的数据源类型,代表不同的业务场景,例如:OrgInfo是事件的基础数据,OrgAddInfo代表新增,OrgDeleteInfo代表删除等。然后根据不同的数据类型,创建监听,但是发现只有OrgInfo的监听生效了,并且是多次生效,其他监听都不生效。

    数据

    基础数据

    @Data
    @AllArgsConstructor
    @NoArgsConstructor
    public class OrgInfo implements Serializable {
        private Integer id;
        private String name;
    
        @Override
        public String toString() {
            return "OrgInfo{" +
                    "id=" + id +
                    ", name='" + name + '\'' +
                    '}';
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15

    业务扩展数据

    @Data
    @AllArgsConstructor
    @NoArgsConstructor
    public class OrgAddInfo extends OrgInfo {
        private String address;
    
        public OrgAddInfo(int id, String name, String address) {
            super(id, name);
            this.address = address;
        }
    
        @Override
        public String toString() {
            return "OrgAddInfo{" +
                    "address='" + address + '\'' +
                    "} " + super.toString();
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18

    事件

    请注意:该事件的数据是带有泛型约束。<S extends OrgInfo>:通过泛型约束,事件的数据源既可以是OrgInfo,也可以是OrgAddInfo,是不是可以通过这种形式,实现一个事件多个业务操作(机构变更事件:新增操作、修改操作、删除操作)?

    public class OrgChangeEvent extends ApplicationEvent {
    
        public OrgChangeEvent(S source) {
            super(source);
        }
    
        public S getSource() {
            return (S) super.getSource();
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

    监听

    新增操作的监听

    public class OrgAddListener implements ApplicationListener> {
        @Override
        public void onApplicationEvent(OrgChangeEvent event) {
            System.out.println("org info event add " + event.toString());
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    普通操作的监听

    public class OrgListener implements ApplicationListener> {
        @Override
        public void onApplicationEvent(OrgChangeEvent event) {
            System.out.println("org info event:" + event.toString());
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    发布事件

    public static void main(String[] args) {
            AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext();
           applicationContext.register(OrgListener.class);
            applicationContext.register(OrgAddListener.class);
            applicationContext.refresh();
    
            applicationContext.publishEvent(new OrgChangeEvent(new OrgInfo(1, "orgInfo")));
            applicationContext.publishEvent(new OrgChangeEvent(new OrgAddInfo(1, "orgInfoAdd","地址")));
     }
    
            
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11

    输出内容

    org info event:com.jkf.event.listener.org.event.OrgChangeEvent[source=OrgInfo{id=1, name=‘orgInfo’}]

    org info event:com.jkf.event.listener.org.event.OrgChangeEvent[source=OrgAddInfo{address=‘地址’} OrgInfo{id=1, name=‘orgInfoAdd’}]

    全部都是:OrgListener 的输出,并且输出了两次,说明OrgAddListener 的输出并没有生效。

    原因

    因为 applicationContext.publishEvent*(new OrgChangeEvent(new OrgInfo(1, “orgInfo”)))*

    1 根据smartListener.supportsEventType*(eventType):OrgListener肯定能消费new OrgChangeEvent(new OrgInfo(1, “orgInfo”)),第一个输出没有问题。*

    2 new OrgChangeEvent*<OrgAddInfo>(new OrgAddInfo(1, “orgInfoAdd”,“地址”)):OrgChangeEvent在ResolvableType中被识别为OrgChangeEvent,因此在ResolvableType.isAssignableFrom中的泛型比较时,被解析为OrgInfo类,但是监听的数据是OrgAddInfo,两者不同,导致第二个监控未生效。*

    结论

    事件的数据源类型一定要与监听器的数据源类型一致。

    后续熟悉ResolvableType再来分析一波。

  • 相关阅读:
    JavaScript【立即调用的函数(IIFE)、eval 命令、函数的应用、对象概述、对象属性、对象方法、函数应用注意事项、Math对象_静态属性、Math对象_静态方法一】(八)
    大数据培训课程WordCount案例实操
    Win11 22H2怎么卸载更新补丁?Win11 22H2卸载更新补丁的步骤
    Python数据分析--Numpy常用函数介绍(4)--Numpy中的线性关系和数据修剪压缩
    Java真的不难(五十一)SpringBoot使用EasyExcel实现导出
    【CentOS7】vsftpd学习笔记
    linux安装MySQL8.0,密码修改权限配置等常规操作详解
    WebSocket: 实时通信的新维度
    ChatPPT AIGC HR财务行政运营销售职场办公一键PPT生成
    小程序:uniapp解决主包体积过大的问题
  • 原文地址:https://blog.csdn.net/u010652576/article/details/126249294