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

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

  • [5、SpringBoot3 核心](#5、SpringBoot3 核心)
    • [5.1 原始开发](#5.1 原始开发)
    • [5.2 事件驱动开发](#5.2 事件驱动开发)

5、SpringBoot3 核心

5.1 原始开发


  • LoginController
java 复制代码
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 {
    @Autowired
    AccountService accountService;

    @Autowired
    CouponService couponService;

    @Autowired
    SysService 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
java 复制代码
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
java 复制代码
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
java 复制代码
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 登录接口
java 复制代码
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 {
    
    @Autowired
    EventPublisher 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 用户类
java 复制代码
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 事件发送器
java 复制代码
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
     */
    @Override
    public void setApplicationEventPublisher(ApplicationEventPublisher applicationEventPublisher) {
       this.applicationEventPublisher = applicationEventPublisher;
    }
}
  • LoginSuccessEvent 登录成功监听
java 复制代码
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
java 复制代码
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 {

    @EventListener
    public 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 模拟给用户发放优惠卷
java 复制代码
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 {

    @EventListener
    public 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 模拟记录用户登录
java 复制代码
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 {

    @EventListener
    public 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 数字越低优先级越高。如:

java 复制代码
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)
    @EventListener
    public 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 + " 的信息");
    }
}
相关推荐
望获linux1 分钟前
【Linux基础知识系列】第四十三篇 - 基础正则表达式与 grep/sed
linux·运维·服务器·开发语言·前端·操作系统·嵌入式软件
喜欢吃豆6 分钟前
深入企业内部的MCP知识(三):FastMCP工具转换(Tool Transformation)全解析:从适配到增强的工具进化指南
java·前端·人工智能·大模型·github·mcp
用户15517339388310 分钟前
前后端处理 `multipart/form-data` 混合参数(实体对象+文件)方案
java
东阳马生架构13 分钟前
订单初版—3.支付和履约链路中的技术问题说明文档
java
paopaokaka_luck37 分钟前
智能推荐社交分享小程序(websocket即时通讯、协同过滤算法、时间衰减因子模型、热度得分算法)
数据库·vue.js·spring boot·后端·websocket·小程序
留不住丨晚霞44 分钟前
说说SpringBoot常用的注解?
java·开发语言
华科云商xiao徐1 小时前
Java多线程爬虫动态线程管理实现
java·爬虫·数据挖掘
hardStudy_h1 小时前
C++——内联函数与Lambda表达式
开发语言·jvm·c++
柒七爱吃麻辣烫1 小时前
八股文系列-----SpringBoot自动配置的流程
java·spring boot·rpc
M1A11 小时前
Java 面试系列第一弹:基础问题大盘点
java·后端·mysql