重生之 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 + " 的信息");
    }
}
相关推荐
懒虫虫~2 小时前
基于SpringBoot利用死信队列解决RabbitMQ业务队列故障重试无效场景问题
spring boot·rabbitmq
卑微的Coder4 小时前
Redis Set集合命令、内部编码及应用场景(详细)
java·数据库·redis
CrissChan4 小时前
Pycharm 函数注释
java·前端·pycharm
moxiaoran57535 小时前
uni-app学习笔记二十九--数据缓存
笔记·学习·uni-app
C++ 老炮儿的技术栈5 小时前
UDP 与 TCP 的区别是什么?
开发语言·c++·windows·算法·visual studio
启航挨踢5 小时前
java学习电子书推荐
java
wgslucky5 小时前
Dubbo报错:module java.base does not “opens java.lang“ to unnamed module
java·开发语言·dubbo
whyeekkk5 小时前
python打卡第48天
开发语言·python
pop_xiaoli6 小时前
OC—UI学习-2
学习·ui·ios
Lin Hsüeh-ch'in6 小时前
Vue 学习路线图(从零到实战)
前端·vue.js·学习