应用启动过程生命周期事件感知(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事件驱动开发的更多相关文章

  1. springboot区分开发、测试、生产多环境的应用配置(二)

    转:https://www.jb51.net/article/139119.htm springboot区分开发.测试.生产多环境的应用配置(二) 这篇文章主要给大家介绍了关于maven profil ...

  2. SpringBoot Web开发(5) 开发页面国际化+登录拦截

    SpringBoot Web开发(5) 开发页面国际化+登录拦截 一.页面国际化 页面国际化目的:根据浏览器语言设置的信息对页面信息进行切换,或者用户点击链接自行对页面语言信息进行切换. **效果演示 ...

  3. SpringBoot Web开发(4) Thymeleaf模板与freemaker

    SpringBoot Web开发(4) Thymeleaf模板与freemaker 一.模板引擎 常用得模板引擎有JSP.Velocity.Freemarker.Thymeleaf SpringBoo ...

  4. springboot区分开发、测试、生产多环境的应用配置

    转:https://blog.csdn.net/daguairen/article/details/79236885 springboot区分开发.测试.生产多环境的应用配置(一) Spring可使用 ...

  5. 千锋很火的SpringBoot实战开发教程视频

    springboot是什么? Spring Boot是由Pivotal团队提供的全新框架,其设计目的是用来简化新Spring应用的初始搭建以及开发过程.该框架使用了特定的方式来进行配置,从而使开发人员 ...

  6. springboot 快速开发的定制补充

    增强 SpringBoot 快速开发工具 项目地址:https://gitee.com/sanri/web-ui 优点:这是一个 web 通用配置的组件,即插即用,可用于新项目或私活.是对 Sprin ...

  7. springboot实战开发全套教程,让开发像搭积木一样简单!Github星标已上10W+!

    前言 先说一下,这份教程在github上面星标已上10W,下面我会一一给大家举例出来全部内容,原链接后面我会发出来!首先我讲一下接下来我们会讲到的知识和技术,对比讲解了多种同类技术的使用手日区别,大家 ...

  8. springboot注解开发

    可以毫不夸张地说,这篇文章介绍的 Spring/SpringBoot 常用注解基本已经涵盖你工作中遇到的大部分常用的场景.对于每一个注解我都说了具体用法,掌握搞懂,使用 SpringBoot 来开发项 ...

  9. SpringBoot快速开发REST服务最佳实践

    一.为什么选择SpringBoot Spring Boot是由Pivotal团队提供的全新框架,被很多业内资深人士认为是可能改变游戏规则的新项目.早期我们搭建一个SSH或者Spring Web应用,需 ...

  10. springboot快速开发(简单web)

    这是一个springboot基础配置文件介绍的demo.只涉及到 控制层与前端的简单交互,用于验证代码的畅通. spring-boot  pom.xml解释 <?xml version=&quo ...

随机推荐

  1. 使用MTR网络诊断

    安装 MTR Ubuntu: apt update apt upgrade apt install mtr-tiny CentOS: yum update yum install mtr 使用 MTR ...

  2. 8款支持 C# 语言的 AI 辅助编程神器,高效编程利器!

    前言 在当今这个AI技术日新月异的时代,一股创新的浪潮正席卷着软件开发领域,其中AI辅助编程工具以其独特的魅力脱颖而出,成为了众多开发者不可或缺的得力助手.这些工具不仅能够显著提升开发效率,优化代码质 ...

  3. ABB机器人IO板DSQC651维修检查方法

    ABB机器人作为工业自动化的重要设备,其稳定性和可靠性对于生产线的持续运行至关重要.然而,在实际使用中,由于各种原因,可能会出现ABB机器人IO板DSQC651故障,影响机器人的正常运行. 一.ABB ...

  4. TDH - 如何显示Guardian Client角色

    注意:本博客适用TDH版本4.3.x 默认该页面的 Guardian Client 是隐藏的,如果需要对 Guardian Client角色进行什么操作的话,需要先将 Guardian Client角 ...

  5. typora编辑数学公式

    最后,需要补充两点: 1.如果要导出为docx,需要安装pandoc https://github.com/jgm/pandoc/releases/tag/3.6.3 2.如果要自己写代码,比如输入\ ...

  6. python excel 读取:如何读取符合多个条件的记录【出差、外出、调休、年假】

    if 语句结合or 实现:读取所有出差.外出.调休.年假的记录 if '出差' in str(c_cell) or '外出' in str(c_cell) or'调休' in str(c_cell) ...

  7. 从RNN、LSTM到NTM、MANN——神经网络的记忆与推理进化

    从RNN.LSTM到NTM.MANN--神经网络的记忆与推理进化 一.前言:为什么要研究记忆? (温馨提示:在阅读本文之前,请确保你已经对深度学习中最基本的概念有一定的了解,例如:激活函数.多层感知机 ...

  8. 【Loongson】支持AXI总线接口

    概述 支持axi接口.但其实没有burst,没有cache,没有tlb,所以仿真起来全是空泡,冲突转发相关功能正确性就测不出来. 从sram改为axi:等待时间从一拍到看信号握手 主要更改/bug处: ...

  9. FastAPI 错误处理与自定义错误消息完全指南:构建健壮的 API 应用 🛠️

    title: FastAPI 错误处理与自定义错误消息完全指南:构建健壮的 API 应用 ️ date: 2025/3/12 updated: 2025/3/12 author: cmdragon e ...

  10. Web前端入门第 11 问:HTML 常用标签有多少?全量标签有多少?

    HELLO,这里是大熊学习前端开发的入门笔记. 本系列笔记基于 windows 系统. 截止发文,MDN 收录的 HTML 全量标签有 126 个,有 18 个标记已弃用. 名词解释:MDN --- ...