重生之 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
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
注意:默认触发顺序是按照字母排序,可以通过 @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 + " 的信息");}
}