首页 > 其他分享 >SpringBoot事件驱动开发

SpringBoot事件驱动开发

时间:2023-10-30 19:56:23浏览次数:32  
标签:core SpringBoot boot3 事件驱动 开发 springframework atguigu import event

应用启动过程生命周期事件感知(9大事件)、应用运行中事件感知(无数种)

  • 事件发布:ApplicationEventPublisherAware或注入:ApplicationEventMulticaster
  • 事件监听:组件 + @EventListener

场景:

当用户登录后,我们需要为用户增加一个积分随机获取一张优惠券增加日志等,传统的开发模式为在用户登录的login()方法后调用积分优惠券日志服务。这样在后续的开发中login()方法可能会频繁变动,根据设计模式方法应该对新增开放,修改关闭,所以可以在login()方法中发布登录成功的事件,在积分优惠券日志服务增加对事件的监听进行后续处理即可。

编写代码

LoginController.java

在login()方法后发布登录成功事件

package com.atguigu.boot3.core.controller;

import com.atguigu.boot3.core.entity.UserEntity;
import com.atguigu.boot3.core.event.EventPublisher;
import com.atguigu.boot3.core.event.LoginSuccessEvent;
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;

/**
 * @date 2023/10/30 18:57
 */
@RestController
public class LoginController {

    @Autowired
    EventPublisher eventPublisher;

    @GetMapping("/login")
    public String login(@RequestParam("username") String username,
                        @RequestParam("passwd")String passwd){
        //业务处理登录
        System.out.println("业务处理登录完成....");
        
        //1、创建事件信息
        LoginSuccessEvent event = new LoginSuccessEvent(new UserEntity(username, passwd));
        //2、发送事件
        eventPublisher.publishEvent(event);

        //设计模式:对新增开放,对修改关闭
        return username+"登录成功";
    }
}

LoginSuccessEvent.java 事件定义

通过继承ApplicationEvent类,将source传给父类对象。

package com.atguigu.boot3.core.event;

import com.atguigu.boot3.core.entity.UserEntity;
import org.springframework.context.ApplicationEvent;

/**
 * 登录成功事件
 * @author 朱俊伟
 * @date 2023/10/30 18:56
 */
public class LoginSuccessEvent  extends ApplicationEvent {

    /**
     * @param source  代表是谁登录成了
     */
    public LoginSuccessEvent(UserEntity source) {
        super(source);
    }
}

EventPublisher.java事件发布器

定义事件发布器,实现ApplicationEventPublisherAware接口,用来发布事件

package com.atguigu.boot3.core.event;

import org.springframework.context.ApplicationEvent;
import org.springframework.context.ApplicationEventPublisher;
import org.springframework.context.ApplicationEventPublisherAware;
import org.springframework.stereotype.Component;

/**
 * @date 2023/10/30 18:58
 */
@Component
public class EventPublisher implements ApplicationEventPublisherAware {

    /**
     * 底层发送事件用的组件,SpringBoot会通过ApplicationEventPublisherAware接口自动注入给我们
     * 事件是广播出去的。所有监听这个事件的监听器都可以收到
     */
    ApplicationEventPublisher applicationEventPublisher;

    @Override
    public void setApplicationEventPublisher(ApplicationEventPublisher applicationEventPublisher) {
        this.applicationEventPublisher = applicationEventPublisher;
    }

    /**
     * 发布事件
     * @param event 事件
     */
    public void publishEvent(LoginSuccessEvent event) {
        applicationEventPublisher.publishEvent(event);
    }
}

CouponService.java 优惠券服务

可以通过给方法定义@EventListener注解,代表该类监听某种事件
可以给监听器使用@Order(1)注解定义监听器的顺序,数字越小,越先执行

package com.atguigu.boot3.core.service;

import com.atguigu.boot3.core.entity.UserEntity;
import com.atguigu.boot3.core.event.LoginSuccessEvent;
import lombok.extern.slf4j.Slf4j;
import org.springframework.context.event.EventListener;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Service;

/**
 * 优惠券服务
 * @date 2023/10/30 19:06
 */
@Service
@Slf4j
public class CouponService {

    @Order(1)
    @EventListener
    public void onEvent(LoginSuccessEvent loginSuccessEvent){
        log.info("CouponService.onEvent....");
        UserEntity user = (UserEntity) loginSuccessEvent.getSource();
        sendCoupon(user);
    }

    public void sendCoupon(String username){
        System.out.println(username + " 随机得到了一张优惠券");
    }

    public void sendCoupon(UserEntity user){
        sendCoupon(user.getUsername());
    }
}

AccountService.java 积分服务

可以实现ApplicationListener接口来监听事件
实现onApplicationEvent方法来进行事件的处理

package com.atguigu.boot3.core.service;

import com.atguigu.boot3.core.entity.UserEntity;
import com.atguigu.boot3.core.event.LoginSuccessEvent;
import lombok.extern.slf4j.Slf4j;
import org.springframework.context.ApplicationListener;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Service;

/**
 * 积分服务
 * @date 2023/10/30 19:03
 */
@Service
@Slf4j
@Order(2)
public class AccountService implements ApplicationListener<LoginSuccessEvent> {

    @Override
    public void onApplicationEvent(LoginSuccessEvent event) {
      log.info("AccountService.onApplicationEvent.....");
        UserEntity user = (UserEntity) event.getSource();
        addAccountScore(user);
    }

    public void addAccountScore(UserEntity user){
        System.out.println(user.getUsername() +" 加了1分");
    }

}

SysService.java 日志服务

package com.atguigu.boot3.core.service;

import com.atguigu.boot3.core.entity.UserEntity;
import com.atguigu.boot3.core.event.LoginSuccessEvent;
import lombok.extern.slf4j.Slf4j;
import org.springframework.context.event.EventListener;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Service;

/**
 * 日志服务
 * @date 2023/10/30 19:09
 */
@Service
@Slf4j
public class SysService {

    @EventListener
    @Order(3)
    public void onEvent(LoginSuccessEvent event){
        log.info("SysService.onEvent....");
        UserEntity user = (UserEntity) event.getSource();
        recordLog(user);
    }

    public void recordLog(UserEntity user){
        System.out.println(user.getUsername() + "登录信息已被记录");
    }
}

UserEntity.java实体类

package com.atguigu.boot3.core.entity;

import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;

/**
 * @date 2023/10/30 18:55
 */
@AllArgsConstructor
@NoArgsConstructor
@Data
@Builder
public class UserEntity {

    private String username;
    private String passwd;
}

调用

http://localhost:8080/login?username=admin&passwd=123

控制台打印结果

业务处理登录完成....
2023-10-30T19:20:11.670+08:00  INFO 11984 --- [nio-8080-exec-5] c.a.boot3.core.service.CouponService     : CouponService.onEvent....
admin 随机得到了一张优惠券
2023-10-30T19:20:11.671+08:00  INFO 11984 --- [nio-8080-exec-5] c.a.boot3.core.service.AccountService    : AccountService.onApplicationEvent.....
admin 加了1分
2023-10-30T19:20:11.671+08:00  INFO 11984 --- [nio-8080-exec-5] c.atguigu.boot3.core.service.SysService  : SysService.onEvent....
admin登录信息已被记录

在业务类中增加方法来实现对事件的监听个人感觉是比较好的方法,可以更好的调节事件处理的顺序以及减少业务类对实现接口的定义。

参考:

https://www.yuque.com/leifengyang/springboot3/lliphvul8b19pqxp#Cq1vD

标签:core,SpringBoot,boot3,事件驱动,开发,springframework,atguigu,import,event
From: https://www.cnblogs.com/zjw-blog/p/17798650.html

相关文章

  • 安卓app开发注意事项及部分源码分享
    随着智能手机的普及,安卓app开发已成为当今的热门领域,在开发过程中,为了提高app的质量和用户体验,需要注意一些关键事项,同时掌握部分源码也是非常必要的。一、安卓app开发注意事项1、安全问题在安卓app开发中,安全问题至关重要,用户数据泄露、恶意等安全问题会给用户带来严重损失,为了确......
  • 敏捷开发企业级内训-Scrum
    课程概述 Scrum是目前运用最为广泛的敏捷开发方法,是一个轻量级的项目管理和产品研发管理框架。这是一个两天的实训课程,面向研发管理者、项目经理、产品经理、研发团队等,旨在帮助学员全面系统地学习Scrum和敏捷开发,帮助企业快速启动敏捷实施。课程采用案例讲解+沙盘演练的方式......
  • 回收废品抢派单小程序开源版开发
    回收废品派单抢派单小程序开源版开发在这个废品回收抢单派单小程序开源版开发中,我们将构建一个专业且富有趣味性的平台,以深度的模式来重塑废品回收体验。我们将提供一个会员注册功能,用户可以通过小程序授权注册和手机号注册两种方式快速加入我们的平台。这不仅方便了用户,同时也为平......
  • SpringBoot事件和监听器
    事件和监听器生命周期监听场景:监听应用的生命周期监听器-SpringApplicationRunListener自定义SpringApplicationRunListener来监听事件;1.1.编写SpringApplicationRunListener实现类1.2.在META-INF/spring.factories中配置org.springframework.boot.SpringApplication......
  • [Springboot整合thymeleaf]处理js中的路径问题。
    使用了thymeleaf模板引擎之后,html中的标签,都可以直接替换成th:srcth:href但是处理js的中的资源路径并不是像jsp那么简单了。可以通过以下方式解决。<!--处理路径问题--><scriptth:inline="javascript">varpath=[[${#request.contextPath}]]</script><scriptth:inl......
  • 管理类App开发步骤及部分源码分享
    随着移动互联网的快速发展,企业对于管理类App的需求也在不断增加,管理类App可以帮助企业实现更高效、更便捷的管理和协作,同时也可以提高员工的工作效率和生产力。一、需求分析在开发管理类App之前,需要进行充分的需求分析,这个阶段主要是明确App的开发目标和用户需求,包括用户群体、功能......
  • Flutter web开发
    dependencies:flutter:sdk:flutterdio:^5.3.3get:^4.6.6shared_preferences:^2.2.2firebase_core:^2.5.0firebase_analytics:^10.1.1firebase_performance:^0.9.0+11flutter:uses-material-design:false编译项目工程:flutterbuildweb使用本地服务器检查......
  • 桶装水送水多门店水票押金押桶小程序开发
    桶装水送水多门店水票押金押桶小程序开发1.用户注册和登录2.首页展示各门店的桶装水品牌和价格3.用户可以选择门店和水品牌,并下单购买桶装水4.用户可以选择送水时间和地址5.用户可以查看自己的订单历史和当前订单状态6.用户可以申请退款或修改订单信息7.门店可以登录后台管......
  • 作为前端开发,你应该知道的这十几个在线免费工具
    偶然刷到知乎一位前端大佬 @表歌 多篇优秀实用的文章,真的发现宝藏了以下内容就是他在知乎分享的十几个在线免费工具1. 页面设计检查清单:https://www.checklist.design/页面设计检查清单通过清单可以检查一些常用容易忽略的设计要素。2.背景色生成:https://webgradients.com/?ref......
  • 低代码开发是不是“简易低智”的玩具?看这篇就够了
        低代码的概念自2014年由研究机构Forrester提出以来,已经在国外市场逐渐成熟,形成了稳定的商业模式。而在国内,从2018年开始,这一理念逐渐受到广泛关注,尽管初期伴随着一些质疑的声音,如“简易低智”、“新瓶旧酒”等批评,甚至有观点认为这只是一些“外包公司”贴上的新标签。......