SpringBoot中ApplicationEvent和ApplicationListener用法小结

作者:一缕82年的清风 时间:2021-08-11 07:43:04 

对不起大家,昨天文章里的告别说早了,这个系列还不能就这么结束。

我们前面的文章中讲解过RabbitMQ的用法,所谓MQ就是一种发布订阅模式的消息模型。在Spring中其实本身也为我们提供了一种发布订阅模式的事件处理方式,就是ApplicationEvent和 ApplicationListener,这是一种基于观察者模式实现事件监听功能。也已帮助我们完成业务逻辑的解耦,提高程序的扩展性和可维护性。

但是这里要注意ApplicationEvent和 MQ队列虽然实现的功能相似,但是MQ还是有其不可替代性的,最本质的区别就是MQ可以用于不同系统之间的消息发布,而SpringEvent这种模式只能在一个系统中,也就是要求必须是同一个Spring容器。

好了接下来我们就来演练一番。

在这个模型中,有两个重要的类,一个是事件,一个是监听。事件要继承ApplicationEvent类,监听要实现ApplicationListener接口。

一、开发ApplicationEvent事件

事件其实就是我们要发送的消息体,这个一般要根据我们的实际业务进行封装,需要什么类型的数据,就是用什么类型,需要哪些字段就添加哪些字段。我们来给一个案例。

package com.lsqingfeng.springboot.applicationEvent;

import lombok.Getter;
import lombok.Setter;
import org.springframework.context.ApplicationEvent;

/**
* @className: MyApplicationEvent
* @description: 事件封装
* @author: sh.Liu
* @date: 2022-03-23 14:41
*/
@Getter
@Setter
@ToString
public class MyApplicationEvent extends ApplicationEvent {

private Integer age;

private String name;

/**
    * 需要重写构造方法
    * @param source
    * @param name
    * @param age
    */
   public MyApplicationEvent(Object source, String name, Integer age) {
       super(source);
       this.name = name;
       this.age = age;
   }
}

二、 开发 *

* 就相当于我们的MQ的消费者,当有时间推送过来的时候, * 的代码就可以执行。这里通过泛型来设置好我们的事件类型。

package com.lsqingfeng.springboot.applicationEvent;

import org.springframework.context.ApplicationListener;
import org.springframework.stereotype.Component;

/**
* @className: MyApplicationEventListener
* @description:事件 *
* @author: sh.Liu
* @date: 2022-03-23 14:50
*/
@Component
public class MyApplicationEventListener implements ApplicationListener<MyApplicationEvent> {

@Override
   public void onApplicationEvent(MyApplicationEvent event) {
       System.out.println("收到消息:" + event);
   }
}

三、推送事件

推送事件需要使用ApplicationEventPublisher。这个对象在Spring容器加载的时候就已经在容器中了。所以我们可以直接注入使用,也可以使用ApplicationContext,因为ApplicationContext本身就继承了ApplicationEventPublisher。 我们通过一个Controller来验证一下。

package com.lsqingfeng.springboot.controller;

import com.lsqingfeng.springboot.applicationEvent.MyApplicationEvent;
import com.lsqingfeng.springboot.base.Result;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

/**
* @className: ApplicationEventController
* @description:
* @author: sh.Liu
* @date: 2022-03-23 15:21
*/
@RestController
@RequestMapping("event")
public class ApplicationEventController {

@Autowired
   private ApplicationContext applicationContext;

@RequestMapping("/push")
   public Result pushEvent(){
       MyApplicationEvent myApplicationEvent = new MyApplicationEvent(this,"zhangsan", 10);
       applicationContext.publishEvent(myApplicationEvent);
       return Result.success();
   }

@RequestMapping("/push2")
   public Result pushEvent2(){
       applicationContext.publishEvent("大家好");
       return Result.success();
   }
}

我们定义两个推送的方法。一个推送我们的MyApplicationEvent类型,还有一个方法推送一个字符串。

当我们调用第一个方法的时候,控制台可以打印出我们推送的数据信息。

SpringBoot中ApplicationEvent和ApplicationListener用法小结

调用推送字符串的时候,我们的 * 不会执行,原因是我们的 * 里已经加了泛型MyApplicationEvent,也就是只会监听MyApplicationEvent类型的消息。其他类型的消息不会被监听到。

那如果我们把泛型去掉会有什么效果呢,我们来试试。

SpringBoot中ApplicationEvent和ApplicationListener用法小结

每次推送都会发送两条(可能有什么内部机制,不管了),但是两个都打印了,说明如果不加泛型,不管谁推,这边都能收到消息。

四、注解方式实现 *

除了上面的通过实现接口的方式开发 * ,我们还可以通过注解的方式来实现,具体代码如下。

package com.lsqingfeng.springboot.applicationEvent;

import org.springframework.context.event.EventListener;
import org.springframework.stereotype.Component;

/**
* @className: MyApplicationEventListener2
* @description: 注解实现 *
* @author: sh.Liu
* @date: 2022-03-23 15:56
*/
@Component
public class MyApplicationEventListener2 {

@EventListener
   public void onEvent(MyApplicationEvent event){
       System.out.println("收到消息2:" + event);
   }
}

这里加入了@EventListener 注解代表了这是一个 * 。方法名随意,方法里的参数代表监听的事件类型。

再次调用push方法:

SpringBoot中ApplicationEvent和ApplicationListener用法小结

发现两个 * 的数据都会打印。这一特点大家要注意一下。

来源:https://blog.csdn.net/lsqingfeng/article/details/123730365

标签:Spring,Boot,ApplicationEvent
0
投稿

猜你喜欢

  • Mybatis动态调用表名和字段名的解决方法

    2022-03-18 16:54:14
  • javascript 在线文本编辑器实现代码

    2023-11-24 23:07:24
  • 为什么wait和notify必须放在synchronized中使用

    2022-07-20 07:32:39
  • Java中OAuth2.0第三方授权原理与实战

    2021-09-27 01:48:57
  • MyBatis常用的jdbcType数据类型

    2023-09-18 19:09:35
  • C#字符集编码的使用及说明

    2023-12-05 02:06:05
  • C# 根据字符串生成二维码的实例代码

    2023-09-16 09:06:50
  • win10和win7下java开发环境配置教程

    2022-05-01 05:34:22
  • java实现文件下载的两种方式

    2023-11-11 06:37:14
  • JSON Web Token(JWT)原理入门教程详解

    2023-02-05 06:34:43
  • Android 无障碍全局悬浮窗实现示例

    2023-07-30 08:50:01
  • C#使用委托实现的快速排序算法实例

    2022-01-22 18:29:52
  • JAVA设置手动提交事务,回滚事务,提交事务的操作

    2022-07-20 08:07:40
  • SpringBoot项目读取外置logback配置文件的问题及解决

    2023-06-06 10:50:22
  • java获取整点与凌晨的时间戳

    2022-11-10 20:41:58
  • C#格式化json字符串的方法分析

    2023-12-23 00:20:36
  • C#使用protobuf-net进行序列化的详细操作

    2021-11-17 02:32:41
  • java并发编程工具类JUC之ArrayBlockingQueue

    2023-07-04 21:02:20
  • java调用回调机制详解

    2023-11-14 21:53:21
  • Mybatis表的关联查询详情

    2023-11-23 12:15:03
  • asp之家 软件编程 m.aspxhome.com