SpringBoot事件驱动开发
应用启动过程生命周期事件感知(9大事件)、应用运行中事件感知(无数种)
- 事件发布:
ApplicationEventPublisherAware或注入:ApplicationEventMulticaster - 事件监听:
组件 + @EventListener
场景:
当用户登录后,我们需要为用户增加一个积分、随机获取一张优惠券、增加日志等,传统的开发模式为在用户登录的login()方法后调用积分、优惠券、日志服务。这样在后续的开发中login()方法可能会频繁变动,根据设计模式方法应该对新增开放,修改关闭,所以可以在login()方法中发布登录成功的事件,在积分、优惠券、日志服务增加对事件的监听进行后续处理即可。

编写代码
LoginController.java
在login()方法后发布登录成功事件
package com.atguigu.boot3.core.controller;
import com.atguigu.boot3.core.entity.UserEntity;
import com.atguigu.boot3.core.event.EventPublisher;
import com.atguigu.boot3.core.event.LoginSuccessEvent;
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;
/**
* @date 2023/10/30 18:57
*/
@RestController
public class LoginController {
@Autowired
EventPublisher eventPublisher;
@GetMapping("/login")
public String login(@RequestParam("username") String username,
@RequestParam("passwd")String passwd){
//业务处理登录
System.out.println("业务处理登录完成....");
//1、创建事件信息
LoginSuccessEvent event = new LoginSuccessEvent(new UserEntity(username, passwd));
//2、发送事件
eventPublisher.publishEvent(event);
//设计模式:对新增开放,对修改关闭
return username+"登录成功";
}
}
LoginSuccessEvent.java 事件定义
通过继承ApplicationEvent类,将source传给父类对象。
package com.atguigu.boot3.core.event;
import com.atguigu.boot3.core.entity.UserEntity;
import org.springframework.context.ApplicationEvent;
/**
* 登录成功事件
* @author 朱俊伟
* @date 2023/10/30 18:56
*/
public class LoginSuccessEvent extends ApplicationEvent {
/**
* @param source 代表是谁登录成了
*/
public LoginSuccessEvent(UserEntity source) {
super(source);
}
}
EventPublisher.java事件发布器
定义事件发布器,实现
ApplicationEventPublisherAware接口,用来发布事件
package com.atguigu.boot3.core.event;
import org.springframework.context.ApplicationEvent;
import org.springframework.context.ApplicationEventPublisher;
import org.springframework.context.ApplicationEventPublisherAware;
import org.springframework.stereotype.Component;
/**
* @date 2023/10/30 18:58
*/
@Component
public class EventPublisher implements ApplicationEventPublisherAware {
/**
* 底层发送事件用的组件,SpringBoot会通过ApplicationEventPublisherAware接口自动注入给我们
* 事件是广播出去的。所有监听这个事件的监听器都可以收到
*/
ApplicationEventPublisher applicationEventPublisher;
@Override
public void setApplicationEventPublisher(ApplicationEventPublisher applicationEventPublisher) {
this.applicationEventPublisher = applicationEventPublisher;
}
/**
* 发布事件
* @param event 事件
*/
public void publishEvent(LoginSuccessEvent event) {
applicationEventPublisher.publishEvent(event);
}
}
CouponService.java 优惠券服务
可以通过给方法定义
@EventListener注解,代表该类监听某种事件
可以给监听器使用@Order(1)注解定义监听器的顺序,数字越小,越先执行
package com.atguigu.boot3.core.service;
import com.atguigu.boot3.core.entity.UserEntity;
import com.atguigu.boot3.core.event.LoginSuccessEvent;
import lombok.extern.slf4j.Slf4j;
import org.springframework.context.event.EventListener;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Service;
/**
* 优惠券服务
* @date 2023/10/30 19:06
*/
@Service
@Slf4j
public class CouponService {
@Order(1)
@EventListener
public void onEvent(LoginSuccessEvent loginSuccessEvent){
log.info("CouponService.onEvent....");
UserEntity user = (UserEntity) loginSuccessEvent.getSource();
sendCoupon(user);
}
public void sendCoupon(String username){
System.out.println(username + " 随机得到了一张优惠券");
}
public void sendCoupon(UserEntity user){
sendCoupon(user.getUsername());
}
}
AccountService.java 积分服务
可以实现
ApplicationListener接口来监听事件
实现onApplicationEvent方法来进行事件的处理
package com.atguigu.boot3.core.service;
import com.atguigu.boot3.core.entity.UserEntity;
import com.atguigu.boot3.core.event.LoginSuccessEvent;
import lombok.extern.slf4j.Slf4j;
import org.springframework.context.ApplicationListener;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Service;
/**
* 积分服务
* @date 2023/10/30 19:03
*/
@Service
@Slf4j
@Order(2)
public class AccountService implements ApplicationListener<LoginSuccessEvent> {
@Override
public void onApplicationEvent(LoginSuccessEvent event) {
log.info("AccountService.onApplicationEvent.....");
UserEntity user = (UserEntity) event.getSource();
addAccountScore(user);
}
public void addAccountScore(UserEntity user){
System.out.println(user.getUsername() +" 加了1分");
}
}
SysService.java 日志服务
package com.atguigu.boot3.core.service;
import com.atguigu.boot3.core.entity.UserEntity;
import com.atguigu.boot3.core.event.LoginSuccessEvent;
import lombok.extern.slf4j.Slf4j;
import org.springframework.context.event.EventListener;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Service;
/**
* 日志服务
* @date 2023/10/30 19:09
*/
@Service
@Slf4j
public class SysService {
@EventListener
@Order(3)
public void onEvent(LoginSuccessEvent event){
log.info("SysService.onEvent....");
UserEntity user = (UserEntity) event.getSource();
recordLog(user);
}
public void recordLog(UserEntity user){
System.out.println(user.getUsername() + "登录信息已被记录");
}
}
UserEntity.java实体类
package com.atguigu.boot3.core.entity;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
/**
* @date 2023/10/30 18:55
*/
@AllArgsConstructor
@NoArgsConstructor
@Data
@Builder
public class UserEntity {
private String username;
private String passwd;
}
调用
http://localhost:8080/login?username=admin&passwd=123
控制台打印结果
业务处理登录完成....
2023-10-30T19:20:11.670+08:00 INFO 11984 --- [nio-8080-exec-5] c.a.boot3.core.service.CouponService : CouponService.onEvent....
admin 随机得到了一张优惠券
2023-10-30T19:20:11.671+08:00 INFO 11984 --- [nio-8080-exec-5] c.a.boot3.core.service.AccountService : AccountService.onApplicationEvent.....
admin 加了1分
2023-10-30T19:20:11.671+08:00 INFO 11984 --- [nio-8080-exec-5] c.atguigu.boot3.core.service.SysService : SysService.onEvent....
admin登录信息已被记录
在业务类中增加方法来实现对事件的监听个人感觉是比较好的方法,可以更好的调节事件处理的顺序以及减少业务类对实现接口的定义。
参考:
https://www.yuque.com/leifengyang/springboot3/lliphvul8b19pqxp#Cq1vD
SpringBoot事件驱动开发的更多相关文章
- springboot区分开发、测试、生产多环境的应用配置(二)
转:https://www.jb51.net/article/139119.htm springboot区分开发.测试.生产多环境的应用配置(二) 这篇文章主要给大家介绍了关于maven profil ...
- SpringBoot Web开发(5) 开发页面国际化+登录拦截
SpringBoot Web开发(5) 开发页面国际化+登录拦截 一.页面国际化 页面国际化目的:根据浏览器语言设置的信息对页面信息进行切换,或者用户点击链接自行对页面语言信息进行切换. **效果演示 ...
- SpringBoot Web开发(4) Thymeleaf模板与freemaker
SpringBoot Web开发(4) Thymeleaf模板与freemaker 一.模板引擎 常用得模板引擎有JSP.Velocity.Freemarker.Thymeleaf SpringBoo ...
- springboot区分开发、测试、生产多环境的应用配置
转:https://blog.csdn.net/daguairen/article/details/79236885 springboot区分开发.测试.生产多环境的应用配置(一) Spring可使用 ...
- 千锋很火的SpringBoot实战开发教程视频
springboot是什么? Spring Boot是由Pivotal团队提供的全新框架,其设计目的是用来简化新Spring应用的初始搭建以及开发过程.该框架使用了特定的方式来进行配置,从而使开发人员 ...
- springboot 快速开发的定制补充
增强 SpringBoot 快速开发工具 项目地址:https://gitee.com/sanri/web-ui 优点:这是一个 web 通用配置的组件,即插即用,可用于新项目或私活.是对 Sprin ...
- springboot实战开发全套教程,让开发像搭积木一样简单!Github星标已上10W+!
前言 先说一下,这份教程在github上面星标已上10W,下面我会一一给大家举例出来全部内容,原链接后面我会发出来!首先我讲一下接下来我们会讲到的知识和技术,对比讲解了多种同类技术的使用手日区别,大家 ...
- springboot注解开发
可以毫不夸张地说,这篇文章介绍的 Spring/SpringBoot 常用注解基本已经涵盖你工作中遇到的大部分常用的场景.对于每一个注解我都说了具体用法,掌握搞懂,使用 SpringBoot 来开发项 ...
- SpringBoot快速开发REST服务最佳实践
一.为什么选择SpringBoot Spring Boot是由Pivotal团队提供的全新框架,被很多业内资深人士认为是可能改变游戏规则的新项目.早期我们搭建一个SSH或者Spring Web应用,需 ...
- springboot快速开发(简单web)
这是一个springboot基础配置文件介绍的demo.只涉及到 控制层与前端的简单交互,用于验证代码的畅通. spring-boot pom.xml解释 <?xml version=&quo ...
随机推荐
- 通讯录管理系统(C++基础知识实现)
通讯录管理系统 描述:本人C++小白一枚,正在学习C++基础知识,给大家分享一款使用C++基础知识实现的通讯录管理系统,一起努力进步,大佬轻点喷. 1. 知识点 (1) 预处理器指令 (#includ ...
- Spark常用Sql
一.日期处理 1.查询当前日期 SELECT current_date() 2023-12-22 2.查询当前时间戳 select current_timestamp() 2023-12-22 14: ...
- FLink09的RichFlatMap和RichMap使用
一.数据源配置 pom文件:https://www.cnblogs.com/robots2/p/16048648.html 二.RichFlatMap代码,输入单行输出多行 package net.x ...
- TIPTOP应付账款流程学习
应付账款流程与应收账款流程是财务管理的开端,也是财务工作的主要流程. 企业的应付账款有很多种,如原材料的应付账款.电力能源的应付账款.房租的应付账款等,大头是原材料的应付账款,以下详细说明. 在讲解之 ...
- flutter ios 深色模式下状态栏文字是白色的,白色背景下看不见
flutter ios 深色模式下状态栏文字是白色的,白色背景下看不见 theme: ThemeData( appBarTheme: const AppBarTheme( systemOverlayS ...
- JUC并发—5.AQS源码分析一
大纲 1.JUC中的Lock接口 2.如何实现具有阻塞或唤醒功能的锁 3.AQS抽象队列同步器的理解 4.基于AQS实现的ReentractLock 5.ReentractLock如何获取锁 6.AQ ...
- led色块是什么,bin指值是什么
色块其实就是色温的区域范围. LED的色温按标准是分段的, 既然是分段,就有一个最大值和最小值,在色坐标系中是一个,X和Y的坐标对应的也就有一个最大值和最小值,这样一个色温段就是以小块的区域,即所谓的 ...
- Android开发之定时任务(AlarmManager、WorkManager)
Android 程序的定时任务主要有AlarmManager.WorkManager两种. 一.AlarmManager AlarmManager,又称闹钟,可以设置一次性任务,周期重复任务,定时重复 ...
- IDM 下载器 汉化注册激活
将以下程序更改为.bat文件.使用windows的管理员权限打开. 汉化于:https://github.com/WindowsAddict/IDM-Activation-Script @setloc ...
- Vue3响应式编程三剑客:计算属性、方法与侦听器深度实战指南
在Vue3开发中,计算属性.方法和侦听器是处理数据逻辑的核心工具.它们各自有不同的作用和适用场景,合理使用这些工具可以显著提升代码的可读性和性能.本篇将深入探讨这三者的定义.使用场景以及实际案例,并通 ...
