• 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再来分析一波。

  • 相关阅读:
    【JavaEE】JVM 剖析
    (附源码)springboot托育教案系统 毕业设计 224545
    Jmeter用于接口测试中,关联如何实现
    python笔记Ⅴ----元组、字典、集合
    使用Keras的面部表情识别
    基于射频指纹的LoRa网络安全方案研究
    【数据分享】2014-2022年我国淘宝村点位数据(Excel格式/Shp格式)
    如何修复老照片?这三个方法建议收藏
    面向未来的自动化:拥抱机器人即服务(RaaS)
    HC32_HC32F072FAUA_ADC内部温度传感器
  • 原文地址:https://blog.csdn.net/u010652576/article/details/126249294