李莫愁给张无忌朋友圈点赞?详解SpringBoot事件机制

news2024/11/24 16:04:50

Spring Boot的事件机制是基于Spring框架的事件机制实现的。Spring Boot中的事件机制可以让我们在应用程序中监听和响应特定的事件,例如应用程序启动、关闭、上下文刷新等。

接下来,我们通过一个案例,来讲解具体怎么使用。

这个案例就是李莫愁给张无忌点赞。

初窥门径

首先,我们需要定义一个点赞事件类,用于表示朋友圈状态被点赞的事件:

public class LikeEvent {
    private String statusId; // 朋友圈状态的ID
    private String liker; // 点赞者的微信号

    public LikeEvent(String statusId, String liker) {
        this.statusId = statusId;
        this.liker = liker;
    }

    public String getStatusId() {
        return statusId;
    }

    public String getLiker() {
        return liker;
    }
}

然后,我们需要定义一个朋友圈状态类,用于表示朋友圈中的一条状态:

@Data
public class Status {
    private String id; // 状态的ID
    private String userName; // 状态的ID
    private String content; // 状态的内容
    private List<String> likes; // 点赞者的微信号列表

    public Status(String id,String userName, String content) {
        this.id = id;
        this.userName = userName;
        this.content = content;
        this.likes = new ArrayList<>();
    }

    
}

接下来,我们需要定义一个朋友圈服务类,用于发布朋友圈状态和处理点赞事件:

@Service
public class MomentsService {
    public static Map<String, Status> statuses = new HashMap<>(); // 朋友圈状态的ID到状态对象的映射

    @Autowired
    private ApplicationEventPublisher publisher; // 事件发布器

    public String postStatus(String userName , String content) {
        String id = UUID.randomUUID().toString(); // 生成一个随机的ID
        Status status = new Status(id, userName,content);
        statuses.put(id, status);
        return id;
    }

    public void likeStatus(String statusId, String liker) {
        Status status = statuses.get(statusId);
        if (status != null) {
            status.addLike(liker);
            publisher.publishEvent(new LikeEvent(statusId, liker)); // 发布点赞事件
        }
    }


}

在这个服务类中,我们使用了Spring的事件机制来处理点赞事件。当一个朋友圈状态被点赞时,我们会发布一个点赞事件。

然后,我们专门定义一个监听器类,用来处理点赞事件。

@Component
public class MomentsListener {
    @EventListener
    public void handleLikeEvent(LikeEvent event) {
        String statusId = event.getStatusId();
        String liker = event.getLiker();
        Status status = statuses.get(statusId);
        if (status != null) {
            System.out.println(liker + " 点赞了 " + status.getUserName() + "的动态:" + status.getContent());
            System.out.println("当前点赞列表:" + status.getLikes());

        }
    }
}

测试:

@Resource
MomentsService momentsService;

@Test
public void testEvent(){
    User user1 = User.builder().userName("张无忌").build();
    User user2 = User.builder().userName("李莫愁").build();
    User user3 = User.builder().userName("周芷若").build();
    //发张无忌布一条动态,返回朋友圈状态ID
    String statusId = momentsService.postStatus(user1.getUserName(), "今天天气真好!");
    //李莫愁来点赞
    momentsService.likeStatus(statusId,user2.getUserName());
    //周芷若也来点赞
    momentsService.likeStatus(statusId,user3.getUserName());
}

结果:

原理进阶

@EventListener是Spring框架中用于监听事件的注解,它的原理是基于观察者模式实现的。当一个事件被发布时,所有监听该事件的方法都会被调用。

在Spring中,事件的发布者是ApplicationEventPublisher接口,它定义了一个publishEvent方法,用于发布事件。当调用publisher.publishEvent(new LikeEvent(statusId, liker))时,会将LikeEvent事件发布出去,所有监听该事件的方法都会被调用。

在处理LikeEvent事件时,Spring会根据方法参数的类型来确定哪些方法可以处理该事件。例如,如果一个方法的参数类型是LikeEvent,那么它就可以处理LikeEvent事件。当有多个方法可以处理同一个事件时,Spring会根据@Order注解或者实现Ordered接口来确定方法的执行顺序。

具体来说,当调用publisher.publishEvent(new LikeEvent(statusId, liker))时,Spring会在容器中查找所有标注了@EventListener注解的方法,并将LikeEvent事件传递给这些方法进行处理。如果一个方法的参数类型与LikeEvent事件匹配,那么它就会被调用。

例如,假设有一个handleLikeEvent方法,它的参数类型是LikeEvent,那么当调用publisher.publishEvent(new LikeEvent(statusId, liker))时,Spring会将LikeEvent事件传递给handleLikeEvent方法进行处理。

总之,@EventListener注解的原理是基于观察者模式实现的,它可以让我们方便地监听和处理事件。当一个事件被发布时,所有监听该事件的方法都会被调用,Spring会根据方法参数的类型来确定哪些方法可以处理该事件。

必须说透

有的同学看到这里会有问题,为什么要用这种事件模式,我在点赞的时候直接调用处理点赞的方法不就行了吗?

使用事件模式可以将代码解耦,使得代码更加灵活和可扩展。如果直接调用处理点赞的方法,那么每次需要添加新的功能或者修改现有功能时,都需要修改这个方法,这样会导致代码的耦合度很高,难以维护和扩展。

而使用事件模式,可以将点赞事件和处理点赞的方法分离开来,当有新的功能需要添加时,只需要添加一个新的事件处理器即可,不需要修改原有的代码,这样可以大大提高代码的可维护性和可扩展性。

比如,我现在有一个需求,有人点赞后,还要打印动态的点赞总数,是不是只能去修改点赞方法了呢?

可是如果用事件,只需要再一个 @EventListener 即可。

@EventListener
public void handleLikeEvent2(LikeEvent event) {
    String statusId = event.getStatusId();
    Status status = statuses.get(statusId);
    if (status != null) {
        System.out.println("当前点赞总数:" + status.getLikes().size());

    }
}

只需要增加这段代码,其他任何地方都不要动,就是这么爽!

测试结果:

 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/539562.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

一文看懂增值税发票识别OCR:从技术原理到 API Java 示例代码接入

引言 增值税发票识别OCR API是一项重要的技术创新&#xff0c;它在如今信息化的商业环境中发挥着重要作用。通过利用该API&#xff0c;企业和机构能够实现增值税发票的自动化识别和信息提取&#xff0c;从而在财务管理、票据核对、报销流程等方面带来许多好处。 本文将详细介…

Istio virtual service 超时和重试

在使用xshell去远程连接服务器的时候没有反应&#xff0c;这样可能等了几分钟&#xff0c;这样按下crtlc终止就行了。 有些时候微服务是多个服务组成的&#xff0c;a服务会去调用b服务&#xff0c;可能因为网络问题或者连接问题&#xff0c;没有连接成功&#xff0c;那么会尝试…

怎么把音频的声音调大?

怎么把音频的声音调大&#xff1f;我们平时会经常使用到音频文件&#xff0c;但声音大小不一&#xff0c;可能会让我们感到不适应。如果太大&#xff0c;甚至会使人吓一跳&#xff1b;如果太小&#xff0c;则难以听清楚。为了轻松聆听音频&#xff0c;我们需要将声音调整到合适…

ConvNeXt网络详解,最新ConvNeXt结合YOLO,催生YOLOv5目标检测巨变

目录 引言一、ConvNeXt的介绍1、目标检测的重要性2、YOLOv5的介绍3、ConvNeXt原理和特点4、ConvNeXt结构 二、相关研究综述1、目标检测的基础原理和流程2、YOLOv5的特点与局限性3、ConvNeXt技术在目标检测中的应用现状 三、ConvNeXt在YOLOv5中的应用与改进1、安装PyTorch和torc…

什么是栈,为什么函数式编程语言都离不开栈?

文章目录 一、什么是栈&#xff0c;什么是FILO二、栈的作用是什么&#xff0c;为什么编程语言函数调用都选择用栈&#xff1f;三、使用C模拟实现解析栈1.结构体的定义2.栈的创建及销毁3.实现入栈操作4.获取栈顶元素及出栈操作5.获取栈中有效元素个数 源代码分享 一、什么是栈&a…

临时被拉去已经在进行中的项目组「救火」,该怎么开展管理?

当你被临时拉去参与正在进行中的项目组&#xff0c;需要进行所谓的「救火」工作时&#xff0c;你需要注意的是如何开展管理&#xff0c;以确保项目能够成功完成。 首先&#xff0c;你需要了解项目的当前状态。了解项目的进展情况、目标和计划&#xff0c;以及团队成员的角色和…

Vmware Linux磁盘空间扩容

Linux磁盘空间扩容 VMware虚拟机中配置&#xff08;1&#xff09;进入虚拟机设置界面&#xff0c;选择扩展磁盘容量。&#xff08;2&#xff09; 本次是在原来30G的基础上扩展为50G。 Linux中设置&#xff08;1&#xff09; 可以看出sda3是根分区&#xff0c;下面按照博客提示&…

栈的实现(附含经典例题)

&#x1f349;博客主页&#xff1a;阿博历练记 &#x1f4d6;文章专栏&#xff1a;数据结构与算法 &#x1f68d;代码仓库&#xff1a;阿博编程日记 &#x1f365;欢迎关注&#xff1a;欢迎友友们点赞收藏关注哦&#x1f339; 文章目录 &#x1f340;前言&#x1f3c4;‍♂️数…

Redis系列--哨兵模式

一、什么是哨兵 Redis Sentinel&#xff08;哨兵&#xff09;是一个分布式系统,你可以在一个架构中运行多个哨兵(sentinel) 进程, 这些进程使用 gossip协议(基于流行病传播方式的节点或者进程之间信息交换的协议&#xff0c;在分布式系统中被广泛使用) 来接收关于Master是否下线…

MySQL5.0完全卸载教程

一、停止MySQL服务 在系统服务中找到mysql服务并停止即可。 二、卸载mysql应用程序 在控制面板中卸载mysql应用程序 三、删除mysql文件夹 找到mysql一开始安装路径的文件夹&#xff0c;然后删除掉该整个文件夹。 四、删除注册表 &#xff08;1&#xff09;按winR键&#xff0c;…

架构师日记-从代码到设计的性能优化指南 | 京东云技术团队

一 前言 服务性能是指服务在特定条件下的响应速度、吞吐量和资源利用率等方面的表现。据统计&#xff0c;性能优化方面的精力投入&#xff0c;通常占软件开发周期的10%到25%左右&#xff0c;当然这和应用的性质和规模有关。性能对提高用户体验&#xff0c;保证系统可靠性&…

Java经典笔试题—day10

Java经典笔试题—day10 &#x1f50e;选择题&#x1f50e;编程题&#x1f95d;井字棋&#x1f95d;密码强度等级 &#x1f50e;结尾 &#x1f50e;选择题 (1)下列运算符合法的是&#xff08; &#xff09; A.&& B.<> C.if D.: A B. 泛型的标志, 例如 <T>…

【iOS】—— AFNetworking源码学习

AFNetworking 文章目录 AFNetworkingAFHTTPSessionManager *sessionManager [AFHTTPSessionManager manager];请求过程1、调用请求序列化类中的requestWithMethod方法进行序列化处理2、调用dataTaskWithRequest来生成一个datatask任务 AFURLSessionMangerAFHTTPSessionManagerU…

Linux服务器--基线检查

Linux服务器--基线检查 一、前言二、口令策略2.1 检查项—密码策略2.2 检查项—密码生存期2.3 检查项—检查密码生存期是否作用于每个用户 三、账号管理3.1 检查项—禁止存在UID相同的用户3.1 检查项—禁止存在空密码的帐户 四、认证授权4.1 检查项—登陆失败处理 五、文件权限…

Pytroch 模型权重初始化

目录 1 概念 2 权值初始化方法 2.1 常数初始化 2.2 均匀分布初始化 2.3 正态分布初始化 2.4 Xavier 均匀分布 2.5 Xavier 正态分布 2.6 kaiming 均匀分布 2.7 kaiming 正态分布 2.8 单位矩阵初始化 2.9 正交初始化 2.10 稀疏初始化 2.11 狄拉克δ函数初始化 3 py…

STC15通过内部BandGap电压值测量ADC外部输入电压

STC15通过内部BandGap参考电压值测量ADC通道外部输入电压 📜内部 BandGap参考电压值获取方式: 🎬通过VOFA图形化显示ADC值 🔧vofa+工具下载地址:https://www.vofa.plus/🌿验证对象:IAP15F2K61S2🌿时钟频率:11.0592MHz🌿波特率:115200🔖在通过STC-ISP烧录程序…

XSS攻击以及java应对措施

文章目录 一. XSS攻击介绍1. 前端安全2. xss攻击简介3. xss的攻击方式 二. java应对xss攻击的解决方案1. 强制修改html敏感标签内容2. 利用过滤器过滤非法html标签 一. XSS攻击介绍 1. 前端安全 随着互联网的高速发展&#xff0c;信息安全问题已经成为企业最为关注的焦点之一…

大脑的故事

婴⼉的神经元是相互独⽴的、未连接的。在⼈⽣的头两年&#xff0c; 随着⼤脑细胞接收感觉信息&#xff0c;它们异常迅速地连接起来。 每⼀秒就有多达 200万个新连接&#xff08;突触&#xff09;在婴⼉的⼤脑⾥形成。两岁时&#xff0c;⼩孩⼦拥有超过 100万亿个突触&#xff…

版本发布 | 科东软件Intewell-Win V2.1.0 release版本正式发布

Intewell是由科东软件自主研发的工业嵌入式实时操作系统&#xff0c;具有高实时&#xff0c;确定性、高安全、高可靠、虚拟化等特点。Intewell系统源自于1990年诞生的“道”操作系统&#xff0c;至今已有30多年历史&#xff0c;已在多种严苛环境下运行检验&#xff0c;广泛商用…

springboot+java超市收银管理系统idea

考虑到实际生活中在超市 POS 收银管理方面的需要以及对该系统认真的分析&#xff0c;将系统权限按管理员和员工这两类涉及用户划分。 Spring Boot 是 Spring 家族中的一个全新的框架&#xff0c;它用来简化Spring应用程序的创建和开发过程。也可以说 Spring Boot 能简化我们之…