重生之 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 + " 的信息");
    }
}
相关推荐
dadaobusi1 分钟前
RV设备透传:主线尚未支持
学习
驭渊的小故事11 分钟前
多线程02
java·开发语言·jvm
阿里嘎多学长14 分钟前
2026-09-09 GitHub 热点项目精选
开发语言·程序员·github·代码托管
xqqxqxxq15 分钟前
AI Agent学习:主动工具发现(李博杰《深入理解 AI Agent》4.8观后总结)
人工智能·学习
随遇而安zx17 分钟前
【多线程】---实战:CompletableFuture编排
java·多线程·并发
Wang's Blog24 分钟前
Java框架快速入门: Spring Security+OAuth2之HTTP请求结构与认证基础
java·spring·http
君顾129 分钟前
本地折扣卡 CPS 平台搭建:从系统架构到落地实战
java·开发语言·折扣卡
liangshanbo12151 小时前
手写 Function.prototype.call 与 Function.prototype.apply 面试题满分答案
开发语言·javascript·原型模式
Zenova EdgeOS1 小时前
C++ 工业边缘 libcurl HTTP 客户端实战
开发语言·c++·网络协议·边缘计算
爱吃苹果的日记本2 小时前
数据结构第一课
c语言·数据结构·数据库·学习·c#