【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)

大家都在看

  • 在laravel中使用pipeline管道提升redis读写速度

    可能有些小伙伴使用redis读写数据在需要循环使用的场景会发现效率并不是很高 于是我分享一个pipeline管道方法 我们这里用12万条数据做测试,首先来试试写入操作,看看用常规方…

    数据库 2023年6月14日
    0107
  • mysql常用操作汇总

    工作中经常用会遇到这种情况,可以访问mysql所在的服务器,但是服务器端口不对外暴露(通常因为安全原因)。这时,操作数据库只能通过命令行和 mysql client窗口来实现。我对…

    数据库 2023年5月24日
    084
  • springboot使用Redis,监听Redis键过期的事件设置与使用代码

    我使用的是Windows下的Redis服务,所以一下Redis设置都是在Windows平台进行。 1、修改Redis配置文件 1.1:Windows下的Redis存在两个配置文件 …

    数据库 2023年6月16日
    098
  • Go语言常见的并发模式

    Go语言常见的并发模式 并发不是并行 并发关注的是程序的设计层面,并发的程序也可以顺序执行,在多核CPU上才可能真正同时的运行,并行关注的是程序的运行层面,如GPU中对图像处理都会…

    数据库 2023年6月16日
    077
  • MySQL基础入门学习教程,带你快速掌握mysql

    Original: https://www.cnblogs.com/chaichaichai/p/15243386.htmlAuthor: 牛仔码农Title: MySQL基础入门…

    数据库 2023年5月24日
    0117
  • 数据库的常用命令

    1. 数据操作类语句: SELECT:从数据库表&#x4E2D…

    数据库 2023年5月24日
    0108
  • windows环境下nacos集群启动报错-无法启动内嵌的tomcat

    解决办法:使用64位jdk切记不要使用32位。切记不要使用32位。切记不要使用32位。 Original: https://www.cnblogs.com/journeyhch/p…

    数据库 2023年6月11日
    085
  • 小心陷入MySQL索引的坑

    索引可以说是数据库中的一个大心脏了,如果说一个数据库少了索引,那么数据库本身存在的意义就不大了,和普通的文件没什么两样。所以说一个好的索引对数据库系统尤其重要,今天来说说MySQL…

    数据库 2023年6月6日
    098
  • Dubbo源码(三)-服务导出(生产者)

    前言 本文基于Dubbo2.6.x版本,中文注释版源码已上传github:xiaoguyu/dubbo 在了解了Dubbo SPI后,我们来了解下Dubbo服务导出的过程。 Dub…

    数据库 2023年6月11日
    096
  • MySQL 服务无法启动。服务没有报告任何错误。

    版本8.0.25,今天启动发现抱错,网上搜索一下发现这样可行 启动MySQL报错: 搜索了一下,按照这样步骤解决了 1.配置一下my.ini [mysqld] basedir =&…

    数据库 2023年6月16日
    096
  • MYSQL–>函数与约束条件

    函数最常用的地方就是查询语句处 select 函数(字段) from &#x8868…

    数据库 2023年6月14日
    098
  • django-Celery分布式队列简单使用

    介绍: Celery 是一个简单、灵活且可靠的,处理大量消息的分布式系统,并且提供维护这样一个系统的必需工具。 它是一个专注于实时处理的任务队列,同时也支持任务调度。 worker…

    数据库 2023年6月6日
    0101
  • Linux 服务管理

    Linux 服务管理 1. 基本介绍 服务的本质就是进程,但是是运行在后台的,通常都会监听某个端口,等待其它程序的请求,比如mysqld,sshd,防火墙等,因此我们又称为守护线程…

    数据库 2023年6月6日
    0104
  • Linux–>定时任务调度

    指定系统在某个时间执行特点的命令或程序。 任务调度分类: crontab 选项 常用选项 选项 说明 -e 编辑crontab定时任务 -l 查询crontab任务 -r 删除当前…

    数据库 2023年6月14日
    073
  • mysql主从

    mysql主从 mysql主从 1.主从原理 1.1 主从介绍 1.2 主从作用 1.3 主从形式 1.4 主从复制原理 2.主从复制配置 2.1 mysql安装 2.2 mysq…

    数据库 2023年5月24日
    079
  • Golang异常处理

    从error的定义说起 type error interface { Error() string } Go 的error类型是一个接口。在Go中,只要实现了接口约定的方法,就等同…

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