SpringBoot中事件的使用

2023-05-16

        项目中很多场景可以使用事件来对系统进行解耦,让系统更便于维护和扩展。SpringBoot项目默认是支持事件的,我们只需要自定义事件,然后发布事件,之后监听事件处理业务逻辑即可。SpringBoot中我们会用到事件抽象类ApplicaltionEvent,事件监听接口ApplicationListener,事件发布接口ApplicationEventPublisher或ApplicationContextAware。

事件发布无论是用ApplicationEventPublisher还是ApplicationContextAware都可以,实际上都是调用了publishEvent(ApplicationEvent event)方法进行事件发布。

从Springboot源码来看,ApplicationContextAware 接口定义了一个set方法,用于注入ApplicationContext 对象,而ApplicationContext继承ApplicationEventPublisher接口。

public interface ApplicationContextAware extends Aware {
    void setApplicationContext(ApplicationContext var1) throws BeansException;
}
@FunctionalInterface
public interface ApplicationEventPublisher {
    default void publishEvent(ApplicationEvent event) {
        this.publishEvent((Object)event);
    }

    void publishEvent(Object var1);
}
public interface ApplicationContext extends EnvironmentCapable, ListableBeanFactory, HierarchicalBeanFactory, MessageSource, ApplicationEventPublisher, ResourcePatternResolver {
    @Nullable
    String getId();

    String getApplicationName();

    String getDisplayName();

    long getStartupDate();

    @Nullable
    ApplicationContext getParent();

    AutowireCapableBeanFactory getAutowireCapableBeanFactory() throws IllegalStateException;
}

使用示例如下:

1.定义一个事件,事件需要继承ApplicationEvent,否则无法发布。

package com.xmc.event;

import org.springframework.context.ApplicationEvent;

import java.util.Map;

/**
 * 定义一个事件
 */
public class SmsEvent extends ApplicationEvent {
    // 事件参数
    private Map<String, String> map;
    public SmsEvent(Object source, Map<String,String> map) {
        super(source);
        this.map = map;
    }

    public Map<String,String> getParam() {
        return map;
    }
}

2.编写Service层代码,用于事件发布。

以下分别是通过注入ApplicationEventPublisher 对象和实现ApplicationContextAware接口通过setter方式注入ApplicationContext对象的方式,来调用publishEvent方法发布事件。

@Service
public class SmsService {
    @Autowired
    private ApplicationEventPublisher applicationEventPublisher;

    /**
     * 发布事件
     * @param smsEvent
     */
    public void SendSms(SmsEvent smsEvent) {
        applicationEventPublisher.publishEvent(smsEvent);
    }
}
package com.xmc.service;

import com.xmc.event.SmsEvent;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.context.ApplicationEventPublisher;
import org.springframework.stereotype.Service;

@Service
public class SmsService2 implements ApplicationContextAware {

    private ApplicationContext applicationContext;

    @Override
    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
        this.applicationContext = applicationContext;
    }

    /**
     * 发布事件
     * @param smsEvent
     */
    public void SendSms(SmsEvent smsEvent) {
        applicationContext.publishEvent(smsEvent);
    }


}

3.编写controller层代码

package com.xmc.controller;

import com.xmc.event.SmsEvent;
import com.xmc.service.SmsService;
import com.xmc.service.SmsService2;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RestController;

import java.util.HashMap;
import java.util.Map;

@RestController
public class UserRegisterController {
    @Autowired
    private SmsService smsService;

    @Autowired
    private SmsService2 SmsService2;

    @GetMapping("/registerUser")
    public String registerUser()  {
        Map<String,String> map = new HashMap<>();
        map.put("phone", "12345678901");
        SmsEvent smsEvent = new SmsEvent(this, map);
        smsService.SendSms(smsEvent);
        return "注册成功";
    }

    @GetMapping("/registerUser2")
    public String registerUser2()  {
        Map<String,String> map = new HashMap<>();
        map.put("phone", "12345678902");
        SmsEvent smsEvent = new SmsEvent(this, map);
        SmsService2.SendSms(smsEvent);
        return "注册成功2";
    }
}

4.编写listener监听器,用监听器来执行发送短信任务。一般来说实现了ApplicationListener接口后,要把事件类型作为泛型传入。如果不传入事件类型的泛型, 则重写onApplicationEvent方法后就是public void onApplicationEvent(ApplicationEvent event), 需要通过event.getSource()拿到关心的类型再做处理。

package com.xmc.listener;

import com.xmc.event.SmsEvent;
import org.springframework.context.ApplicationListener;
import org.springframework.stereotype.Component;

/**
 * 事件监听器
 */
@Component
public class SmsListener implements ApplicationListener<SmsEvent> {
    @Override
    public void onApplicationEvent(SmsEvent smsEvent) {
        System.out.println("正在向手机号:" + smsEvent.getParam().get("phone") + "发送短信");
    }
}

测试结果:

正在向手机号:12345678901发送短信

正在向手机号:12345678902发送短信

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

SpringBoot中事件的使用 的相关文章

随机推荐

  • 解决电脑wlan被禁用无法再启动的办法.

    快捷键ctrl 43 alt 43 delete打开任务管理器 gt 选择服务 gt 左下角打开服务 gt 找到WLAN AutoConfig右键 gt 选择重新启动 xff0c 然后Ok了
  • 关于虚拟机ubuntu编译程序时报make: warning: Clock skew detected. Your build may be incomplete.问题的解决办法

    关于ubuntu虚拟机编译程序时报make warning Clock skew detected Your build may be incomplete 问题的解决办法 xff1a 我在ubuntu虚拟的arm linux gcc上编译
  • 解决rosbag时间戳未对齐的解决方法

    解决rosbag时间戳未对齐的解决方法 Reference ROS org rosbag Cookbook http wiki ros org rosbag Cookbook rosbag在存储时间时 xff0c 接收消息的时间和生成消息的
  • ROS+python控制小乌龟走方形的实现rospy

    常见的简陋的控制乌龟行走方形的方式很简单 xff0c 例如 xff1a 代码有些地方是测试用的 xff0c 可以不要 usr bin env python from pickle import TRUE import rospy from
  • C++ STL算法

    C 43 43 STL算法 1 非修正序列算法1 1 adjacent find first last 1 2 count first last val 2 修正序列算法2 1 random shuffle first last 2 2 p
  • git子模块的修改和更新操作

    Reference git子模块的修改和更新操作 1 子库与父库 git关于子模块的官方文档链接 xff1a https git scm com book zh v2 Git E5 B7 A5 E5 85 B7 E5 AD 90 E6 A8
  • CMakeLists Option使用简介

    CMakeLists Option使用简介 1 基本格式2 示例3 基本用法4 C程序条件编译5 次项目之间选项的关系 Reference xff1a CMake之Option使用简介 CMake中的option用于控制编译流程 xff0c
  • 四轴一键起飞定高定点悬停伪代码

    四轴飞行器一键起飞定高 xff0c 降落 xff0c 光流定点悬停控制算法伪代码 基于飞控系统的二次开发
  • 开源飞控地面站 Openpilot GCS (现在的Librepilot GCS)源码分析  (2)地图插件

    xff08 xff11 xff09 OpenPilot项目中有地图显示模块 xff08 xff12 xff09 地图显示模块的插件是 xff1a opmap插件 xff0c 位置是src gt plugins gt opmap xff08
  • ubuntu 下运行程序报错 对‘std::cout’未定义的引用:gcc与g++的区别

    目录 1 问题提出 2 gcc与g 43 43 的区别 2 1 预处理 2 2 编译 2 3 汇编 2 4 链接运行 3 总结 1 问题提出 linux初学 xff0c 写了个例程 xff0c 用gcc o编译时出现以下问题 xff1a 后
  • 2.2 开启调度器

    开启调度器 void vTaskStartScheduler void BaseType t xReturn if configSUPPORT STATIC ALLOCATION 61 61 1 静态创建空闲任务 StaticTask t
  • 4. 消息队列

    消息队列 队列又称消息队列 xff0c 常用于任务间通信的数据结构 xff0c 可以在任务与任务之间 xff0c 中断与任务之间传递消息 xff0c 实现任务接收来自其他任务或中断的不固定长度的消息 任务可从消息队列中读取消消息 xff0c
  • 网卡接口

    网络接口 网络接口 xff08 以太网 xff09 是硬件接口 xff0c LwIP是软件 xff0c 并且网卡也是由很多种的 LwIP使用一个数据结构 xff0c nitif来描述网卡 用户提供最底层的接口函数 xff0c LwIP则提供
  • 系统扇区

    系统结构 DBR xff0c 主引导记录 xff1b DPT xff0c 分区表 xff1b DBR xff0c 分区引导扇区 引导扇区 MBR Main Boot Record xff0c 主引导扇区 xff0c 硬盘主引导记录区 xff
  • 华为3COM交换机配置命令详解

    1 配置文件相关命令 Quidway display current configuration 显示当前生效的配置 Quidway display saved configuration xff1b 显示flash中配置文件 xff0c
  • 分区结构

    分区结构 DBR xff0c 引导记录区 xff0c 包括一个引导程序和一个BPB xff0c 即本分区参数记录表 系统可直接访问的第一个扇区 xff0c 大小为512个字节 xff08 特殊情况占用其他保留扇区 xff09 512字节中
  • 1. 列表和列表项

    列表和列表项 列表 列表是一个数据结构 xff0c 用来追踪任务 xff0c 列表中有一个指针指向列表项 列表是一个结构体 xff0c 内部携带一个指针 xff0c 指针指向列表项 xff0c 列表项形成双向链式结构挂载在列表下 一个列表下
  • C#简单串口调试助手【傻瓜教程】chanson_chapter01

    简易串口调试助手制作教程 C Winform chanson chapter01 说明 xff1a 本教程基于win10 x64 位操作系统 xff0c 软件环境为Microsoft Visual Studio Community 2015
  • 快速上手Ubuntu之安装篇——安装win7,Ubuntu16.04双系统

    Linux可以说是开发者的系统 xff0c 对于开发者来说 xff0c Linux发行版不仅为我们提供了无数强大的开发工具 xff0c 还能帮助我们从源码上学习操作系统是工作的 而且经常在命令行上工作的我们还能在别人面前耍下酷 Ubuntu
  • SpringBoot中事件的使用

    项目中很多场景可以使用事件来对系统进行解耦 xff0c 让系统更便于维护和扩展 SpringBoot项目默认是支持事件的 xff0c 我们只需要自定义事件 xff0c 然后发布事件 xff0c 之后监听事件处理业务逻辑即可 SpringBo