Spring事件监听机制ApplicationEvent方式

 更新时间:2023年09月21日 09:02:52   作者:爱琴孩  
这篇文章主要介绍了Spring事件监听机制ApplicationEvent方式,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教

前言

ApplicationEvent 以及 Listener 是Spring为我们提供的一个事件监听、订阅的实现,内部实现原理是观察者设计模式,设计初衷也是为了系统业务逻辑之间的解耦,提高可扩展性以及可维护性。

ApplicationEvent的小demo

ApplicationEvent本身是抽象类,无法直接实例化。一般通过子类继承ApplicationEvent

public class MyApplicationEvent extends ApplicationEvent {
    private Student student;
    public Student getStudent() {
        return student;
    }
    public void setStudent(Student student) {
        this.student = student;
    }
    public MyApplicationEvent(Object source) {
        super(source);
    }
    public MyApplicationEvent(Object source, Student student) {
        super(source);
        this.student = student;
    }
}

事件定义好之后,我们注册个事件监听器即可。

实现ApplicationListener接口注册监听器

@Component
public class MyApplicationListener implements ApplicationListener<MyApplicationEvent> {
    private static final Logger LOGGER = LoggerFactory.getLogger(MyApplicationListener.class);
    @Override
    public void onApplicationEvent(MyApplicationEvent myApplicationEvent) {
        Student student = myApplicationEvent.getStudent();
        LOGGER.info("学生对象是={}", JSONObject.toJSONString(student));
    }
}

通过@EventListener注册监听器,ApplicationContext.publishEvent 默认是同步操作, 并非发布后不管的异步操作,发布事件后需要等 @EventListener 执行完。

如果需要开启异步操作 需要在 @EventListener 上 增加 @Async 注解。

@Component
public class AsyncApplicationListener {
    private static final Logger LOGGER = LoggerFactory.getLogger(AsyncApplicationListener.class);
    @EventListener
    @Async
    public void listener(MyApplicationEvent myApplicationEvent) {
        Student student = myApplicationEvent.getStudent();
        LOGGER.info("通过@EventListener获取学生对象信息={}", JSONObject.toJSONString(student));
    }
}

通过实现SmartApplicationListener接口注册监听器

SmartApplicationListener接口继承了全局监听ApplicationListener,并且泛型对象使用的ApplicationEvent来作为全局监听,可以理解为使用SmartApplicationListener作为监听父接口的实现,监听所有事件发布。

既然是监听所有的事件发布,那么SmartApplicationListener接口添加了两个方法supportsEventType、supportsSourceType来作为区分是否是我们监听的事件,只有这两个方法同时返回true时才会执行onApplicationEvent方法。

@Component
public class MySmartApplicationListener implements SmartApplicationListener {
    private static final Logger LOGGER = LoggerFactory.getLogger(MySmartApplicationListener.class);
    @Override
    public boolean supportsEventType(Class<? extends ApplicationEvent> aClass) {
        return aClass == MyApplicationEvent.class;
    }
    @Override
    public boolean supportsSourceType(Class<?> sourceType) {
        return sourceType == ApplicationRunnerTest.class;
    }
    @Override
    public int getOrder() {
        return 0;
    }
    @Override
    public void onApplicationEvent(ApplicationEvent applicationEvent) {
        MyApplicationEvent myApplicationEvent = (MyApplicationEvent) applicationEvent;
        LOGGER.info("通过MySmartApplicationListener 获取学生对象信息={}",
                JSONObject.toJSONString(myApplicationEvent.getStudent()));
    }
}

可以看到除了上面的方法,还提供了一个getOrder方法,这个方法就可以解决执行监听的顺序问题,return的数值越小证明优先级越高,执行顺序越靠前

发布事件

在Spring的Bean中,注入ApplicationContext ,通过ApplicationContext 来进行事件发布

@Autowired
private ApplicationContext applicationContext;
applicationContext.publishEvent(new MyApplicationEvent(this, new Student("爱琴孩", 18)));

运行结果

2023-01-28 10:38:39.696 YYZX_Study 13540 [           main]  INFO c.e.s.s.MySmartApplicationListener          37: 通过MySmartApplicationListener 获取学生对象信息={"age":18,"name":"爱琴孩"}
2023-01-28 10:38:39.696 YYZX_Study 13540 [           main]  INFO c.e.study.service.MyApplicationListener     22: 学生对象是={"age":18,"name":"爱琴孩"}
2023-01-28 10:38:39.696 YYZX_Study 13540 [tOrderService-1]  INFO c.e.s.service.AsyncApplicationListener      25: 通过@EventListener获取学生对象信息={"age":18,"name":"爱琴孩"}

总结

以上为个人经验,希望能给大家一个参考,也希望大家多多支持脚本之家。

相关文章

  • 最简单的spring boot打包docker镜像的实现

    最简单的spring boot打包docker镜像的实现

    这篇文章主要介绍了最简单的spring boot打包docker镜像的实现,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2020-10-10
  • springboot2.0+elasticsearch5.5+rabbitmq搭建搜索服务的坑

    springboot2.0+elasticsearch5.5+rabbitmq搭建搜索服务的坑

    这篇文章主要介绍了springboot2.0+elasticsearch5.5+rabbitmq搭建搜索服务的坑,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2018-06-06
  • 归并排序时间复杂度过程推导详解

    归并排序时间复杂度过程推导详解

    这篇文章主要介绍了C语言实现排序算法之归并排序,对归并排序的原理及实现过程做了非常详细的解读,需要的朋友可以参考下,希望能帮助到你
    2021-08-08
  • 详解java IO流之缓冲流的使用

    详解java IO流之缓冲流的使用

    本文主要介绍了java的IO流中的缓冲流的使用,缓冲流分为字节和字符缓冲流。分享了有关它们的实例代码,具有一定的参考价值,下面跟着小编一起来看下吧
    2017-01-01
  • springboot集成springsecurity 使用OAUTH2做权限管理的教程

    springboot集成springsecurity 使用OAUTH2做权限管理的教程

    这篇文章主要介绍了springboot集成springsecurity 使用OAUTH2做权限管理的教程,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2020-12-12
  • java实现斗地主发牌功能

    java实现斗地主发牌功能

    这篇文章主要为大家详细介绍了java实现斗地主发牌功能,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2020-11-11
  • java常用工具类 UUID、Map工具类

    java常用工具类 UUID、Map工具类

    这篇文章主要为大家详细介绍了Java常用工具类,包括UUID工具类、Map工具类,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2019-05-05
  • spring与mybatis三种整合方法

    spring与mybatis三种整合方法

    这篇文章主要介绍了spring与mybatis三种整合方法,需要的朋友可以参考下
    2017-04-04
  • springIoc及注解的使用实例详解

    springIoc及注解的使用实例详解

    注解(Annotation)是一种在 Java 程序中以元数据的形式对代码进行标记和说明的机制,它可以被添加到类、方法、字段、参数等程序元素上,用于提供额外的信息和指示,本文给大家介绍springIoc及注解的使用,感兴趣的朋友一起看看吧
    2024-02-02
  • 使用maven创建web项目的方法步骤(图文)

    使用maven创建web项目的方法步骤(图文)

    本篇文章主要介绍了使用maven创建web项目的方法步骤,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2018-01-01

最新评论