【java框架】SpringBoot(11) — SpringBoot利用监听事件,实现异步操作

请出主角:Spring当中的事件机制

没错,本节主要讲的是Spring中事件机制:ApplicationEventPublisher,实现监听ApplicationEvent,最后利用事件通知实现通知实现异步操作

【java框架】SpringBoot(11) -- SpringBoot利用监听事件,实现异步操作

1、为什么要实现异步操作

  • 在微服务的情况下,多个服务互相调用,及其耗时,当我们不需要此操作返回时,可以异步执行,调用接口,该接口快速返回,减少接口响应时长。
  • 代码逻辑性清晰,对于需要多个异步操作的可以实现事件的统一管理,不用创建线程池,减少资源的消耗

2、编程过程中有哪些可以去异步执行的

  • 所有耗时、且不需要返回的函数
  • 比如记录日志操作、发送邮件、短信等操作

代码展示(先实战、后原理)

假如我们现在有一个需求,购买会员操作!先来分析具体步骤:

1、在会员用户列表添加该用户(代表该用户已经具有会员标示)

2、发送具体会员的权益

3、给用户添加积分操作

4、发送短信通知

假如有上四步,那么我们可以将发送短信通知作为异步操作。

第一步,创建事件

public class SendMessageEvent extends ApplicationEvent {

    private SendMessageEventDto sendMessageEventDto;

    public SendMessageEvent(Object source) {
        super(source);
    }

    public SendMessageEvent(Object source,SendMessageEventDto dto){
        super(source);
        this.sendMessageEventDto = dto;
    }

    public SendMessageEventDto getDto(){
        return sendMessageEventDto;
    }

    public void setDto(SendMessageEventDto dto){
        this.sendMessageEventDto = dto;
    }

    public class SendMessageEventDto{

        /**
         * 手机号
         */
        private Integer userId;

        /**
         * 手机号
         */
        private String mobile;

        /**
         * 短信模板参数数据体
         */
        private String data;

        public String getMobile() {
            return mobile;
        }

        public void setMobile(String mobile) {
            this.mobile = mobile;
        }
        public String getData() {
            return data;
        }

        public void setData(String data) {
            this.data = data;
        }

        public Integer getUserId() {
            return userId;
        }

        public void setUserId(Integer userId) {
            this.userId = userId;
        }
    }
}

上面代码中首先定义发送短信的一个实体(SendMessageEventDto),将这个实体交给定义的事件管理(SendMessageEvent),该事件继承spring的 ApplicationEvent

第二步,将事件通过spring发布,由spring监听该事件

@Autowired
 private ApplicationEventPublisher applicationEventPublisher;

 /**
  * 组装数据体异步发送短信
  * @param mobile  手机号
  * @param userId   用户ID
  * @param jsonObject  短信所需参数
  */
 public void publishMessage(String mobile,Integer userId,JSONObject jsonObject){
    SendMessageEvent event = new SendMessageEvent(this);
    SendMessageEvent.SendMessageEventDto dto = event.new SendMessageEventDto();
    dto.setData(jsonObject.toString());  //具体业务的数据体
    dto.setMobile(mobile);
    dto.setUserId(userId);
    event.setDto(dto);

    //将事件交给spring监听
    applicationEventPublisher.publishEvent(event);
}

第三步,让具体业务持有该事件,并设置被监听状态

public interface SendMessageEventListener {

    //发送短信
    void sendMessage(SendMessageEvent sendMessageEvent);
}
@Component
public class SendMessageEventListenerImpl implements SendMessageEventListener {

    private Logger logger = LoggerFactory.getLogger(SendMessageEventListenerImpl.class);

    @Autowired
    private MiniProgramClient miniProgramClient;

    @Override
    @Async
    @EventListener
    public void sendMessage(SendMessageEvent sendMessageEvent) {
        try {
            SendMessageEvent.SendMessageEventDto dto = sendMessageEvent.getDto();
            logger.error("发送短信通知开始 ->  数据体为 -> "+ JSON.toJSONString(dto));
            MarketMessageDto messageDto = new MarketMessageDto();
            messageDto.setUserId(dto.getUserId());
            messageDto.setData(dto.getData());
            messageDto.setMobile(dto.getMobile());

            //调用短信服务,发送短信
            miniProgramClient.sendMarketMsg(messageDto);
        }catch (Exception e){
            e.getMessage();
            e.printStackTrace();
        }

    }
}

这里特别注意的是,必须在需要被监听的方法上加上 @EventListener, 然后开启异步 @Async

演示调用,大功告成

public static void main(String[] args) {

     //创建会员逻辑开始

     //1、创建会员用户

     //2、发送会员权益

     //3、给用户添加积分

     //4发送短信
     publishMessage("176********",7465388,具体业务参数的json)

     //返回结果
     return "开通会员成功";
}

OK,到这里就大功告成了,整体流程就是这样,这样当执行到给用户添加积分之后,就可直接返回成功,无须等待发送短信操作。

特别注意:在springBoot项目中使用的话,需要在启动类当中加入注解@EnableAsync

博文转载自掘金博文:

https://juejin.cn/post/6985049438540529694

Original: https://www.cnblogs.com/yif0118/p/15969490.html
Author: 人无名,则可专心练剑
Title: 【java框架】SpringBoot(11) — SpringBoot利用监听事件,实现异步操作

原创文章受到原创版权保护。转载请注明出处:https://www.johngo689.com/575913/

转载文章受原作者版权保护。转载请注明原作者出处!

(0)

大家都在看

  • MySQL高可用安装

    MySQL HA部署 环境准备 创建本地yum源 确认关闭 SELinux 防火墙设置 MySQL安装 使用 root 用户操作创建相关的用户组和用户 上传/解压介质 设置自启动 …

    数据库 2023年5月24日
    099
  • 分库分表真的适合你的系统吗?聊聊分库分表和NewSQL如何选择

    曾几何时,”并发高就分库,数据大就分表”已经成了处理 MySQL 数据增长问题的圣经。 面试官爱问,博主爱写,考生爱背诵,似乎形成了一个闭环。 [En] I…

    数据库 2023年5月24日
    0101
  • 浅谈事务隔离级别、MVCC及相关特性

    文采不是太好,应该会有地方表达不清楚,烦请指正。 需要事先准备测试表: CREATE TABLE test ( id int(11) NOT NULL, name varchar(…

    数据库 2023年6月16日
    083
  • 量子物理

    今天刷了YouTube的量子物理了解到了量子物理的发展史从微观到相对论从原子核到量子纠缠何其快哉 物理学:经典物理,量子物理。经典物理:万有引力量子物理:相对论 Original:…

    数据库 2023年6月11日
    073
  • Jenkins+gitlab+docker+harbor容器化自动部署详细流程

    环境:Linux版本:Centos7 一、更新源:yum update 二、安装docker:yum install docker -y 启动docker: systemctl s…

    数据库 2023年6月16日
    0118
  • 聊天软件的后端架构NIO

    聊天软件等的技术,朋友圈,钉钉,微博分两种技术模式:1.读扩散:也就是拉模式消息会存储到自己的发件箱里面,然后让每个上线的人去拉取未读消息,缺点是每次都要去好多底线去拉取数据,读操…

    数据库 2023年6月16日
    0129
  • 第06章 MySQL多表查询

    第06章 MySQL多表查询 多表查询,也称为关联查询,是指两个或多个表一起完成查询操作。 [En] A multi-table query, also known as an a…

    数据库 2023年5月24日
    075
  • Java学习-第一部分-第二阶段-第二节:枚举和注释

    自定义类实现枚举 先看一个需求 要求创建季节(Season)对象,请设计并完成。 创建Season对象有如下特点 1.季节的值是有限的几个值(spring, summer, aut…

    数据库 2023年6月11日
    080
  • [LeetCode]7. 整数反转

    给出一个 32 位的有符号整数,你需要将这个整数中每位上的数字进行反转。 示例 1: 输入: 123输出: 321示例 2: 输入: -123输出: -321示例 3: 输入: 1…

    数据库 2023年6月9日
    070
  • MySQL启动过程详解一:启动整体流程

    MySQL启动流程如下: 设置进程名 处理配置文件及启动参数以及部分模块初始化,这包括: 2.1 从配置文件中读取选项,把他们放在 argc 和 argv 已有的参数之前 2.2 …

    数据库 2023年6月9日
    054
  • 【01】Spring Boot配置文件相关

    1、Spring Boot 获取属性的属性源,优先级从高到低 (1)命令行参数 (2)java:comp/env里的JNDI属性 (3)JVM系统属性 (4)操作系统的环境变量 (…

    数据库 2023年6月9日
    062
  • Our Feeling

    走过春夏秋冬走过五湖四海就是没有走过你 看过日出日落看过潮起潮落就是看不到你 本文来自博客园,作者:ukyo–BlackJesus,转载请注明原文链接:https://…

    数据库 2023年6月11日
    088
  • Question06-查询”李”姓老师的数量

    问题比较简单,一个单表查询就可以解决,这里就不过多地讲解 Original: https://www.cnblogs.com/OnlyOnYourself-lzw/p/165738…

    数据库 2023年6月16日
    066
  • go interface{}使用

    先上代码 为什么会报错? 因为空接口拥有两个指针,内存布局上会占用两个机器字长。 对于长度为n的空接口切片而言,它的每个元素都是以2机器字长为单位的连续空间,因此总共会占用 2n个…

    数据库 2023年6月9日
    069
  • Redis 生产架构选型对比,一文整治选择困难症

    前言 在写开源项目的时候,想到了要支持多种redis部署方式,于是对于这块的生产环境的架构选型展开调研。 一、引擎版本 推荐使用更新的引擎版本以支持更多的特性, Redis 6.0…

    数据库 2023年6月14日
    078
  • 项目管理构建工具——Maven(基础篇)

    项目管理构建工具——Maven(基础篇) 在前面的内容中我们学习了JDBC并且接触到了jar包概念 在后面我们的实际开发中会接触到很多jar包,jar包的导入需要到互联网上进行就会…

    数据库 2023年6月14日
    073
亲爱的 Coder【最近整理,可免费获取】👉 最新必读书单  | 👏 面试题下载  | 🌎 免费的AI知识星球