重生之 SpringBoot3 入门保姆级学习(18、事件驱动开发解耦合)

重生之 SpringBoot3 入门保姆级学习(18、事件驱动开发解耦合)

  • 5、SpringBoot3 核心
    • 5.1 原始开发
    • 5.2 事件驱动开发

5、SpringBoot3 核心

5.1 原始开发


  • LoginController
package com.zhong.bootcenter.controller;import com.zhong.bootcenter.service.AccountService;
import com.zhong.bootcenter.service.CouponService;
import com.zhong.bootcenter.service.SysService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;/*** @ClassName : LoginController* @Description :* @Author : zhx* @Date: 2024-06-12 15:26*/
@RestController
public class LoginController {@AutowiredAccountService accountService;@AutowiredCouponService couponService;@AutowiredSysService sysService;@GetMapping("/login")public String Login(@RequestParam("username") String username, @RequestParam("password") String password) {// 业务处理登录System.out.println("业务处理完成......");// 1、账户服务:      自动签到加积分// 2、优惠卷服务:    随机发放优惠卷// 3、系统服务:      登记用户的信息accountService.addAccountScore(username);couponService.sendCoupon(username);sysService.SysUser(username);return username;}
}
  • AccountService
package com.zhong.bootcenter.service;import org.springframework.stereotype.Service;/*** @ClassName : AccountService* @Description :* @Author : zhx* @Date: 2024-06-12 15:30*/
@Service
public class AccountService {public void addAccountScore(String username) {System.out.println(username + " 用户积分+1");}
}
  • CouponService
package com.zhong.bootcenter.service;import org.springframework.stereotype.Service;/*** @ClassName : CouponService* @Description :* @Author : zhx* @Date: 2024-06-12 15:33*/
@Service
public class CouponService {public void sendCoupon(String username) {System.out.println(username + " 发了一张优惠价");}
}
  • SysService
package com.zhong.bootcenter.service;import org.springframework.stereotype.Service;/*** @ClassName : SysService* @Description :* @Author : zhx* @Date: 2024-06-12 15:35*/
@Service
public class SysService {public void SysUser(String username) {System.out.println( "记录了 " + username + " 的信息");}
}
http://localhost:8080/login?username=%22xiaozhong%22&password=%22123456%22

image-20240612155331320

image-20240612155247885

5.2 事件驱动开发


设计模式应该是:对新增开发,对修改关闭。

  • LoginController 登录接口
package com.zhong.bootcenter.controller;import com.zhong.bootcenter.entity.UserEntity;
import com.zhong.bootcenter.event.EventPublisher;
import com.zhong.bootcenter.event.LoginSuccessEvent;
import com.zhong.bootcenter.service.AccountService;
import com.zhong.bootcenter.service.CouponService;
import com.zhong.bootcenter.service.SysService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;/*** @ClassName : LoginController* @Description :* @Author : zhx* @Date: 2024-06-12 15:26*/
@RestController
public class LoginController {@AutowiredEventPublisher eventPublisher;@GetMapping("/login")public String Login(@RequestParam("username") String username, @RequestParam("password") String password) {// 业务处理登录System.out.println("业务处理完成......");// 1、账户服务:      自动签到加积分// 2、优惠卷服务:    随机发放优惠卷// 3、系统服务:      登记用户的信息// TODO 发送事件// 1、创建事件信息LoginSuccessEvent event = new LoginSuccessEvent(new UserEntity(username, password));// 2、发送事件eventPublisher.sendEvent(event);return username;}
}
  • UserEntity 用户类
package com.zhong.bootcenter.entity;import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import org.springframework.beans.factory.annotation.Autowired;/*** @ClassName : UserEntity* @Description :* @Author : zhx* @Date: 2024-06-12 16:01*/
@Data
@AllArgsConstructor
@NoArgsConstructor
public class UserEntity {private String username;private String password;
}
  • EventPublisher 事件发送器
package com.zhong.bootcenter.event;import org.springframework.context.ApplicationEvent;
import org.springframework.context.ApplicationEventPublisher;
import org.springframework.context.ApplicationEventPublisherAware;
import org.springframework.stereotype.Service;/*** @ClassName : EventPublisher* @Description :* @Author : zhx* @Date: 2024-06-12 15:58*/
@Service
public class EventPublisher implements ApplicationEventPublisherAware {/*** 底层发事件使用的组件,SpringBoot会通过 ApplicationEventPublisherAware 接口自动注入给我们* 事件是广播出去的,所有监听这个事件的监听器都会收到*/ApplicationEventPublisher applicationEventPublisher;/*** 所有事件都可以发送* @param event*/public void sendEvent(ApplicationEvent event) {// 调用底层 API 发送事件applicationEventPublisher.publishEvent(event);}/*** 会被自动调用,把真正发事件的底层组件给我们注入进来* @param applicationEventPublisher*/@Overridepublic void setApplicationEventPublisher(ApplicationEventPublisher applicationEventPublisher) {this.applicationEventPublisher = applicationEventPublisher;}
}
  • LoginSuccessEvent 登录成功监听
package com.zhong.bootcenter.event;import com.zhong.bootcenter.entity.UserEntity;
import org.springframework.context.ApplicationEvent;/*** @ClassName : LoginSuccessEvent* @Description :   登录成功事件,所有事件都推荐继承 ApplicationEvent* @Author : zhx* @Date: 2024-06-12 16:00*/
public class LoginSuccessEvent extends ApplicationEvent {public LoginSuccessEvent(UserEntity source) {super(source);}
}
  • AccountService 模拟用户积分 +1
package com.zhong.bootcenter.service;import com.zhong.bootcenter.entity.UserEntity;
import com.zhong.bootcenter.event.LoginSuccessEvent;
import org.springframework.context.event.EventListener;
import org.springframework.stereotype.Service;/*** @ClassName : AccountService* @Description :* @Author : zhx* @Date: 2024-06-12 15:30*/
@Service
public class AccountService {@EventListenerpublic void onEvent(LoginSuccessEvent loginSuccessEvent) {System.out.println("===== AccountService =====感知到事件" + loginSuccessEvent);UserEntity source = (UserEntity) loginSuccessEvent.getSource();addAccountScore(source.getUsername());}public void addAccountScore(String username) {System.out.println(username + " 用户积分+1");}
}
  • CouponService 模拟给用户发放优惠卷
package com.zhong.bootcenter.service;import com.zhong.bootcenter.entity.UserEntity;
import com.zhong.bootcenter.event.LoginSuccessEvent;
import org.springframework.context.event.EventListener;
import org.springframework.stereotype.Service;/*** @ClassName : CouponService* @Description :* @Author : zhx* @Date: 2024-06-12 15:33*/
@Service
public class CouponService {@EventListenerpublic void onEvent(LoginSuccessEvent loginSuccessEvent) {System.out.println("===== CouponService =====感知到事件" + loginSuccessEvent);UserEntity source = (UserEntity) loginSuccessEvent.getSource();sendCoupon(source.getUsername());}public void sendCoupon(String username) {System.out.println(username + " 发了一张优惠价");}
}
  • SysService 模拟记录用户登录
package com.zhong.bootcenter.service;import com.zhong.bootcenter.entity.UserEntity;
import com.zhong.bootcenter.event.LoginSuccessEvent;
import org.springframework.context.event.EventListener;
import org.springframework.stereotype.Service;/*** @ClassName : SysService* @Description :* @Author : zhx* @Date: 2024-06-12 15:35*/
@Service
public class SysService {@EventListenerpublic void onEvent(LoginSuccessEvent loginSuccessEvent) {System.out.println("===== SysService =====感知到事件" + loginSuccessEvent);UserEntity source = (UserEntity) loginSuccessEvent.getSource();SysUser(source.getUsername());}public void SysUser(String username) {System.out.println("记录了 " + username + " 的信息");}
}
http://localhost:8080/login?username=%22xiaozhong%22&password=%22123456%22

image-20240612162058455

image-20240612161704787

注意:默认触发顺序是按照字母排序,可以通过 @Order(number) 注解调整顺序,number 数字越低优先级越高。如:

package com.zhong.bootcenter.service;import com.zhong.bootcenter.entity.UserEntity;
import com.zhong.bootcenter.event.LoginSuccessEvent;
import org.springframework.context.event.EventListener;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Service;/*** @ClassName : SysService* @Description :* @Author : zhx* @Date: 2024-06-12 15:35*/
@Service
public class SysService {@Order(1)@EventListenerpublic void onEvent(LoginSuccessEvent loginSuccessEvent) {System.out.println("===== SysService =====感知到事件" + loginSuccessEvent);UserEntity source = (UserEntity) loginSuccessEvent.getSource();SysUser(source.getUsername());}public void SysUser(String username) {System.out.println("记录了 " + username + " 的信息");}
}

image-20240612162722903

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

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

相关文章

爬虫初学篇——看完这些还怕自己入门不了?

初次学习爬虫,知识笔记小分享 学scrapy框架可看:孤寒者博主的【Python爬虫必备—>Scrapy框架快速入门篇——上】 目录🌟 一、🍉基础知识二、🍉http协议:三、🍉解析网页(1) xpath的用…

基于单片机的无线遥控自动翻书机械臂设计

摘 要: 本设备的重点控制部件为单片机,充分实现了其自动化的目的。相关研究表明,它操作简单便捷,使残疾人在翻书时提供了较大的便利,使用价值性极高,具有很大的发展空间。 关键词: 机械臂&…

25天录用!快到飞起的宝藏SSCI,免版面费,1天见刊!毕业评职即刻拿下

本周投稿推荐 SSCI • 中科院2区,6.0-7.0(录用友好) EI • 各领域沾边均可(2天录用) CNKI • 7天录用-检索(急录友好) SCI&EI • 4区生物医学类,0.5-1.0(录用…

【odoo17】富文本小部件widget=“html“的使用

概要 HTML富文本字段通常用于在模型中存储和显示格式化的文本。通过这种字段,用户可以利用HTML标签来格式化文本,从而在前端呈现更丰富的内容。 在Odoo中,HTML字段在没有明确指定widget"html"的情况下,也会默认显示为富…

Windows NT 3.5程序员讲述微软标志性“3D管道”屏幕保护程序的起源故事

人们使用屏保程序来防止 CRT 显示器"烧毁",因为静态图像会永久损坏屏幕。像 3D Pipes 这样的屏保程序能在显示器处于非活动状态时为其提供动画效果,从而保护屏幕并延长其使用寿命。此外,它们还能在用户不使用电脑时为其提供可定制的…

软件安全漏洞分析与发现 复习笔记

1 绪论 本节无考点,仅供了解。 2 基础知识 考点: 汇编码理解和撰写,三种内存地址,不同的页管理方式。windows保护模式可能出题 汇编算法的阅读理解给出汇编片段,理解其意思,输入->输出保护模式…

Aigtek功率放大器参数怎么选型的

功率放大器是电子系统中重要的组成部分,选型合适的功率放大器对系统的性能和可靠性至关重要。本文下面安泰电子将介绍如何选型功率放大器的关键步骤和考虑因素。 首先,确定应用需求。在选型功率放大器之前,确定应用需求是至关重要的第一步。了…

基于机器学习和深度学习的轴承故障诊断方法(Python)

在工业早期,设备故障诊断通常由专家通过观察设备运行中的变量参数并结合自身知识进行诊断。但相比传统的机理分析方法,数据驱动的智能设备故障诊断更能充分提取数据中隐含的故障征兆、因果逻辑等关系。智能设备故障诊断的优势表现在其对海量、多源、高维…

AI日报|跃问App上架加入AI助理竞争!GPTZero获千万美元A轮融资,创始人不到30岁!

文章推荐 AI日报|Luma推出AI视频模型,又一Sora级选手登场?SD3 Medium发布,图中文效果改善明显 AI日报|仅三个月就下架?微软GPT Builder出局AI竞争赛;马斯克将撤回对奥特曼的诉讼 ⭐️搜索“可…

WordPress如何删除内存中的缓存?

今天boke112百科将某篇文章修改分类和内容更新后,发现文章底部的相关文章显示的内容跟文章分类、标签毫无关系,还是显示原来的旧内容。后来查看YIA主题相关文章的代码,才发现相关文章的数据保存到内存中的,而且是永不过期&#xf…

『大模型笔记』Cohere的联合创始人Nick Frosst谈:AGI真的只是幻想吗?

Cohere的联合创始人Nick Frosst谈:AGI真的只是幻想吗? 文章目录 一. 内容总结所有话题缺失话题bullet pointsAGI(通用人工智能)的立场技术应用和现实世界问题Cohere公司及其活动Command-R模型及其功能检索增强生成(RAG)创始团队的背景工具使用的演变哲学探讨建设日活动开…

plsql执行插入sql时提示ora-00001违反唯一约束条件(cif.pk_ywxyys)

1.plsql执行插入sql时提示ora-00001违反唯一约束条件(cif.pk_ywxyys) 原因:因为表中已经存在了这个主键导致的 一般主键都是id,,可以用id值查是否存在这个主键,已存在这个id值的话想插入数据只能改要插的数据的id值了 找到表最大id值,把要插…

图知识蒸馏综述:算法分类与应用分析

源自:软件学报 作者:陈哲涵 黎学臻 注:若出现无法显示完全的情况,可 V 搜索“人工智能技术与咨询”查看完整文章 摘 要 图数据, 如引文网络, 社交网络和交通网络, 广泛地存在现实生活中. 图神经网络凭借强大的表现力受到广泛…

Appium+python自动化(九)- 定位元素工具(义结金兰的两位异性兄弟)(超详解) 密码保护

宏哥微信粉丝群:https://bbs.csdn.net/topics/618423372 有兴趣的可以扫码加入 简介 环境搭建好了,其他方面的知识也准备的差不多了,那么我们就开始下一步元素定位,元素定位宏哥主要介绍如何使用uiautomatorviewer,通…

鸿蒙轻内核A核源码分析系列四(2) 虚拟内存

本文我们来熟悉下OpenHarmony鸿蒙轻内核提供的虚拟内存(Virtual memory)管理模块。 本文中所涉及的源码,以OpenHarmony LiteOS-A内核为例,均可以在开源站点 https://gitee.com/openharmony/kernel_liteos_a 获取。如果涉及开发板…

Aigtek高压放大器在柔性爬行机器人驱动性能研究中的应用

实验名称:柔性爬行机器人的材料测试 研究方向:介电弹性体的最小能量结构是一种利用DE材料的电致变形与柔性框架形变相结合设计的新型柔性驱动器,所谓最小能量是指驱动器在平衡状态时整个系统的能量最小,当系统在外界的电压刺激下就…

10.Docker Compose容器编排

文章目录 Compose简介安装和卸载步骤核心概念compose文件两要素 使用步骤Compose常用命令微服务测试本地编码打包编写Dockerfile文件构建镜像 不使用Compose调试使用Compose调试WordPress测试验证增量更新 Compose简介 ​ docker建议我们每一个容器中只运行一个服务,因为docke…

Memcached深度解析:打造闪电般的数据存储

Memcached是一个高性能的分布式内存对象缓存系统,通过在内存中缓存数据和对象来减少访问数据库的次数,从而加速动态数据库驱动的网站。本文将全面介绍Memcached的基本概念、使用方法、主要作用以及注意事项。 一、Memcached简介 1. Memcached的起源 Me…

开源复刻apple 数学笔记;纯C++实现了ChatGLM系列模型;腾讯混元文生图模型发布新版本并开源训练代码

✨ 1: AI Math Notes AI Math Notes 是一个交互式绘图应用,可绘制并计算数学方程。 AI Math Notes 受到Apple在WWDC 2024上的“Math Notes”演启发,开发的一个互动式绘图应用程序,用户可以在画布上绘制数学方程。一旦方程被绘制完成&#x…