(五)springboot实战——springboot自定义事件的发布和订阅

news2025/2/26 9:31:45

前言

本节内容我们主要介绍一下springboot自定义事件的发布与订阅功能,一些特定应用场景下使用自定义事件发布功能,能大大降低我们代码的耦合性,使得我们应用程序的扩展更加方便。就本身而言,springboot的事件机制是通过观察者设计模式实现。通过ApplicationListener事件监听器实现事件的发布与订阅。我们以登录场景为例,假如用户登录之后,需要发送登录通知、发送邮件通知、发送签到通知,如果按照常规做法,我们可以顺序执行以上操作,但是使用springboot的事件机制,我们可以发布一个登录的事件消息,然后各自去消费登录这个事件消息,这样达到业务解耦的效果。

正文

①创建一个事件发布器,用于发送自定义的消息事件

- 实现代码:通过实现ApplicationEventPublisherAware 接口

package com.yundi.isbc.event.publish;

import org.springframework.context.ApplicationEvent;
import org.springframework.context.ApplicationEventPublisher;
import org.springframework.context.ApplicationEventPublisherAware;
import org.springframework.stereotype.Component;


@Component
public class MyApplicationEventPublisherAware implements ApplicationEventPublisherAware {
    private ApplicationEventPublisher applicationEventPublisher;


    @Override
    public void setApplicationEventPublisher(ApplicationEventPublisher applicationEventPublisher) {
        this.applicationEventPublisher = applicationEventPublisher;
    }

    /**
     * 消息事件发布
     * @param applicationEvent
     */
    public void publishEvent(ApplicationEvent applicationEvent) {
        applicationEventPublisher.publishEvent(applicationEvent);
    }
}

②创建一个登录的自定义消息事件 

- 实现代码:通过继承ApplicationEvent事件实现自定义消息事件

package com.yundi.isbc.event.publish;

import com.yundi.isbc.entity.User;
import org.springframework.context.ApplicationEvent;


public class LoginApplicationEvent extends ApplicationEvent {

    public LoginApplicationEvent(User user) {
        super(user);
    }
}

 ③创建一个用户实体类,用于数据的传输

- 实现代码

package com.yundi.isbc.entity;

import lombok.Data;
import lombok.experimental.Accessors;


@Accessors(chain = true)
@Data
public class User {
    /**
     * 用户名
     */
    private String username;
    /**
     * 密码
     */
    private String password;
}

④创建一个控制器LoginController,用于登录业务处理,并发布登录事件

 - 实现代码

package com.yundi.isbc.controller;

import com.yundi.isbc.entity.User;
import com.yundi.isbc.event.publish.LoginApplicationEvent;
import com.yundi.isbc.event.publish.MyApplicationEventPublisherAware;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
@RequestMapping("/index")
public class LoginController {
    @Autowired
    private MyApplicationEventPublisherAware myApplicationEventPublisherAware;

    @GetMapping("login")
    public String login() {
        //发布登录事件
        myApplicationEventPublisherAware.publishEvent(new LoginApplicationEvent(new User()
                .setUsername("xiaoming").setPassword("123456")));
        //todo 主流程业务处理
        
        return "ok";
    }

}

- 代码说明

⑤ 通过实现ApplicationListener接口,实现登录通知消息的消费,并做相关的业务处理

- 实现代码

package com.yundi.isbc.event.describe;

import com.yundi.isbc.entity.User;
import com.yundi.isbc.event.publish.LoginApplicationEvent;
import org.springframework.context.ApplicationListener;
import org.springframework.stereotype.Service;


@Service
public class LoginNotifyListen implements ApplicationListener<LoginApplicationEvent> {

    public void accumulateLogin(User user) {
        System.out.println("=======登录业务======" + user);
    }

    @Override
    public void onApplicationEvent(LoginApplicationEvent event) {
        System.out.println("===============收到登录通知事件===================");
        User user = (User) event.getSource();
        accumulateLogin(user);
    }
}

⑥通过@EventListener方式订阅消息,实现邮件业务处理,该种方式更加灵活,不用实现ApplicationListener接口

- 实现代码

package com.yundi.isbc.event.describe;

import com.yundi.isbc.entity.User;
import com.yundi.isbc.event.publish.LoginApplicationEvent;
import org.springframework.context.event.EventListener;
import org.springframework.stereotype.Service;


@Service
public class MailNotifyListen {

    public void mailNotify(User user) {
        System.out.println("=======邮件业务======" + user);
    }

    @EventListener
    public void onLoginEvent(LoginApplicationEvent loginApplicationEvent) {
        System.out.println("===============收到登录通知事件===================");
        User user = (User) loginApplicationEvent.getSource();
        mailNotify(user);
    }
}

 ⑦通过@EventListener方式订阅消息,实现签到业务处理

-实现代码

package com.yundi.isbc.event.describe;

import com.yundi.isbc.entity.User;
import com.yundi.isbc.event.publish.LoginApplicationEvent;
import org.springframework.context.event.EventListener;
import org.springframework.stereotype.Service;


@Service
public class SignNotifyListen {

    public void signNotify(User user) {
        System.out.println("=======签到业务======" + user);
    }

    @EventListener
    public void onLoginEvent(LoginApplicationEvent loginApplicationEvent) {
        System.out.println("===============收到登录通知事件===================");
        User user = (User) loginApplicationEvent.getSource();
        signNotify(user);
    }
}

⑧验证结果,访问登录接口,查看控制台,所有订阅事件的业务都能正常订阅消费

结语

关于springboot自定义事件的发布和订阅的内容到这里就结束了,我们下期见。。。。。。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/787546.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Python(三十九)for-in循环

❤️ 专栏简介&#xff1a;本专栏记录了我个人从零开始学习Python编程的过程。在这个专栏中&#xff0c;我将分享我在学习Python的过程中的学习笔记、学习路线以及各个知识点。 ☀️ 专栏适用人群 &#xff1a;本专栏适用于希望学习Python编程的初学者和有一定编程基础的人。无…

JAVA设计模式——模板设计模式(heima)

JAVA设计模式——模板设计模式&#xff08;heima&#xff09; 文章目录 JAVA设计模式——模板设计模式&#xff08;heima&#xff09;一、模板类二、子类2.1 Tom类2.2 Tony类 三、测试类 一、模板类 package _01模板设计模式;public abstract class TextTemplate{public final…

利用FME实现批量提取图斑特征点、关键界址点提取、图斑拐点抽稀,解决出界址点成果表时点数过多问题的方法

目录 一、实现效果 二、实现过程 1.提取图斑界址点 2.计算各界址点的角度 3.筛选提取关键界址点 三、总结 对于范围较大的图斑&#xff0c;界址点数目较大&#xff0c;在出界址点成果表前&#xff0c;往往需要对界址点进行处理&#xff0c;提取出关键特征点作为出界址点成…

数据库集群方案详解

本期直播我们邀请 KaiwuDB 资深解决方案专家周幸骏&#xff0c;为大家分享数据库集群方案详解。周老师毕业于复旦大学数学系&#xff0c;从业 20 余年&#xff0c;曾在 IBM 公司任资深技术专家&#xff0c;并为多家国有大型商业银行提供技术咨询和数据库业务连续方案设计等服务…

IBM:2023 年数据泄露的平均成本将达到 445 万美元

IBM 发布年度《数据泄露成本报告》&#xff0c;显示 2023 年全球数据泄露平均成本达到 445 万美元&#xff0c;比过去 3 年增加了 15%。创下该报告的历史新高。 报告显示&#xff0c;企业在计划如何应对日益增长的数据泄露频率和成本方面存在分歧。研究发现&#xff0c;虽然 95…

Linux学成之路(基础篇)(二十三)MySQL服务(上)

目录 一、概述 一、什么是MySQL 二、数据库能干什么 三、为什么要用数据库&#xff0c;优势、特性&#xff1f; 二、数据库类型 一、关系型数据库 RDBMS 一、概述 二、特点 三、代表产品 二、非关系型数据库 一、概述 二、特点 三、代表产品 三、数据库模型 一、…

【GEE笔记】主成分分析(PCA)算法的实现和应用

前言 主成分分析&#xff08;PCA&#xff09;是一种常用的降维方法&#xff0c;它可以将多个相关的变量转换为少数几个不相关的变量&#xff0c;称为主成分&#xff08;PC&#xff09;。这些主成分可以反映原始变量的大部分信息&#xff0c;同时减少数据的复杂度和冗余性。在遥…

结构型设计模式之组合模式【设计模式系列】

系列文章目录 C技能系列 Linux通信架构系列 C高性能优化编程系列 深入理解软件架构设计系列 高级C并发线程编程 设计模式系列 期待你的关注哦&#xff01;&#xff01;&#xff01; 现在的一切都是为将来的梦想编织翅膀&#xff0c;让梦想在现实中展翅高飞。 Now everythi…

【nginx】nginx中root与alias的区别:

文章目录 root与alias主要区别在于nginx如何解释location后面的uri&#xff0c;这会使两者分别以不同的方式将请求映射到服务器文件上。 root的处理结果是&#xff1a;root路径&#xff0b;location路径 alias的处理结果是&#xff1a;使用alias路径替换location路径 alias是一…

前端配置nginx反向代理

1.下载nginx 2.进入nginx.conf 3.配置 4.将nginx放入前端项目根目录 5.启动后端项目和nginx服务 启动命令 start nginx ; 重新启动命令 nginx -s reload 6.访问localhost就能看到项目了&#xff08;默认80端口&#xff09; 注意&#xff1a;如果nginx配置了域名&#xff0…

Android ConstraintLayout使用攻略

原文链接 Android ConstraintLayout使用攻略 ConstraintLayout是新一代的布局&#xff0c;它汲取了众家之长&#xff0c;把布局的概念进行了大统一&#xff0c;灵活且强大&#xff0c;基本上可以干掉以前所有的常用布局&#xff08;LinearLayout, RelativeLayout和FrameLayout…

94.qt qml-分页Table表格组件

在我们之前学习了87.qt qml-分页组件控件(支持设置任意折叠页数等)_qt分页控件_诺谦的博客-CSDN博客 然后我们又学习了Table实现,所以本章实现一个分页Table表格组件,配合分页控件, 模拟请求服务器数据来实现数据分解效果,因为一般使用分页的时候,一般都是分页请求,避免数…

Flutter的开发环境搭建-图解

前言&#xff1a;Flutter作为一个移动应用开发框架&#xff0c;具有许多优点和一些局限性。最大的优点就是-跨平台开发&#xff1a;Flutter可以在iOS和Android等多个平台上进行跨平台开发&#xff0c;使用一套代码编写应用程序&#xff0c;节省开发时间和成本。 Flutter可以编…

python将大文件拆分为多个小文件

如上图&#xff0c;目前采用单行不停写入的方式&#xff0c;这里是读了两次文件&#xff0c;第一次读取文件是为了获取总行数&#xff0c;第二次读取是取数据内容。 如果只读取一次文件&#xff0c;则会对内存有一定的要求&#xff0c;会需要在第一次读取数据的时候就将文件内…

ONNX Runtime 加速深度学习(C++ 、python)详细介绍

ONNX Runtime 加速深度学习(C 、python)详细介绍 本文在 https://blog.csdn.net/u013250861/article/details/127829944 基础上进行了更改&#xff0c;感谢原作&#xff01; ONNXRuntime(Open Neural Network Exchange)是微软推出的一款针对ONNX模型格式的推理框架&#xff0c…

Redis常用数据类型和使用场景

Redis目前支持5种数据类型&#xff0c;分别是&#xff1a; String&#xff08;字符串&#xff09; List&#xff08;列表&#xff09; Hash&#xff08;字典&#xff09; Set&#xff08;集合&#xff09; Sorted Set&#xff08;有序集合&#xff09; 下面就分别介绍这五…

Qt Core学习日记——第六天QMetaMethod

Qt子类会将每一个函数封装成QMetaMethod存储在对应的QMetaObject中&#xff0c;包括信号、槽函数、普通函数、构造函数、析构函数 函数解析 QMetaMethod::methodSignature 获取方法的签名 比如函数slot2&#xff0c;对应签名是“slot2(int*)” QMetaMethod::name 方法名称。…

13.2.3 【Linux】新增与移除群组

基本上&#xff0c;群组的内容都与这两个文件有关&#xff1a;/etc/group, /etc/gshadow。 群组的内容其实很简单&#xff0c;都是上面两个文件的新增、修改与移除而已。 groupadd 为了让使用者的 UID/GID 成对&#xff0c;建议新建的与使用者私有群组无关的其他群组时&#x…

RabbitMQ入门,springboot整合RabbitMQ

周末的两天没有写文章&#xff0c;因为项目分离出来了一个权限管理平台&#xff0c;花了一点时间整理项目&#xff0c;同时完成了一些功能的开发。 今天这篇文章介绍一下RabbitMQ这个消息中间件&#xff0c;以及通过springboot整合RabbitMQ。 目录 一、初步了解RabbitMQ 二、…

学Java有哪些就业方向?

俗话说&#xff1a;男怕入错行&#xff0c;女怕嫁错郎。众所周知&#xff0c;选工作就是选行业&#xff0c;行业和方向选对了&#xff0c;个人的发展就会随着行业风向青云直上&#xff0c;比同龄人更快的积累到财富。那究竟未来什么会是热门行业呢?这个真的很难预测&#xff0…