重生之 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 + " 的信息");
    }
}
相关推荐
Han.miracle43 分钟前
数据结构——二叉树的从前序与中序遍历序列构造二叉树
java·数据结构·学习·算法·leetcode
北冥湖畔的燕雀2 小时前
C++泛型编程(函数模板以及类模板)
开发语言·c++
Le1Yu2 小时前
分布式事务以及Seata(XA、AT模式)
java
知识分享小能手2 小时前
uni-app 入门学习教程,从入门到精通,uni-app基础扩展 —— 详细知识点与案例(3)
vue.js·学习·ui·微信小程序·小程序·uni-app·编程
寒山李白3 小时前
关于Java项目构建/配置工具方式(Gradle-Groovy、Gradle-Kotlin、Maven)的区别于选择
java·kotlin·gradle·maven
●VON3 小时前
重生之我在大学自学鸿蒙开发第九天-《分布式流转》
学习·华为·云原生·harmonyos·鸿蒙
QX_hao3 小时前
【Go】--map和struct数据类型
开发语言·后端·golang
你好,我叫C小白3 小时前
C语言 循环结构(1)
c语言·开发语言·算法·while·do...while
无妄无望3 小时前
docker学习(4)容器的生命周期与资源控制
java·学习·docker
MC丶科4 小时前
【SpringBoot 快速上手实战系列】5 分钟用 Spring Boot 搭建一个用户管理系统(含前后端分离)!新手也能一次跑通!
java·vue.js·spring boot·后端