Spring中的事件监听器使用学习

一、什么是Spring中的事件监听机制?

        Spring框架中的事件监听机制是一种设计模式,它允许你定义和触发事件,同时允许其他组件监听这些事件并在事件发生时作出响应。这种机制基于观察者模式,提供了一种松耦合的方式来实现组件间的通信。

二、Spring事件监听机制的关键概念

        1. 事件(Event)

        事件是应用程序中的一个信号,表明某个动作已经发生或某个条件已经满足。在Spring中,事件通常是实现ApplicationEvent接口的类来表示的。Spring为我们提供了多种内置的事件类型,如ContextStartedEvent、ContextRefreshedEvent,ContextCloseEvent、ContextStoppedEvent等事件,分别对应于应用程序上下文的不同生命周期阶段。当然我们也可以自定义自己的事件类型,即:通过实现ApplicationEvent接口或扩展ApplicationEvent类。

        2. 事件发布者(Event Publisher)

        事件发布者负责将事件发布出去,然后通过Spring的智能事件派发,把发布的事件派发给对应该事件类型的所有监听器。在Spring中,ApplicationContext自身就是一个事件发布者(因为ApplicationContext接口继承了ApplicationEventPublisher接口),它可以发布应用程序事件(比如ContextRefreshedEvent ,ContextCloseEvent等事件)。【通常我们会让自定义组件实现 ApplicationEventPublisherAware接口,然后实现接口中的如下方法把事件发布者对象注入到组件中】

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

        3. 事件监听器(Event Listener)

        事件监听器是实现ApplicationListener接口的组件,它们可以监听和响应事件。监听器需要实现onApplicationEvent方法,以便在接收到事件时进行处理。此外,Spring给我们提供了一个 @EventListener注解,允许你直接在方法上标注以监听特定类型的事件。当事件发生时,Spring会自动调用这些方法。(注意:事件监听器一定要放入IOC容器中才会生效。)

        4. 事件传播

        事件可以在不同的Spring容器之间传播,例如从子容器传播到父容器。

        5. 同步与异步事件

        Spring支持同步和异步事件处理。

三、实现一个简单的事件监听功能

        需求描述: 程序中有一个添加用户的业务组件,要求当用户添加成功时,发布一个添加用户成功事件,然后通过添加用户成功事件的监听器给管理员发送一封邮件。

1. 业务组件

        

package com.shg.service;

import com.baomidou.mybatisplus.extension.service.IService;
import com.shg.beans.User;

public interface UserService extends IService<User> {

    User addUser(User user);
}
package com.shg.service.impl;

import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.shg.beans.User;
import com.shg.listener.event.UserAddSuccessEvent;
import com.shg.mapper.UserMapper;
import com.shg.service.UserService;
import org.springframework.context.ApplicationEventPublisher;
import org.springframework.context.ApplicationEventPublisherAware;
import org.springframework.stereotype.Service;

@Service("userService")
public class UserServiceImpl extends ServiceImpl<UserMapper, User> implements UserService, ApplicationEventPublisherAware {

    private ApplicationEventPublisher applicationEventPublisher;
    private final UserMapper userMapper;

    public UserServiceImpl(UserMapper userMapper) {
        this.userMapper = userMapper;
    }

    @Override
    public User addUser(User user) {
        userMapper.insert(user);
        applicationEventPublisher.publishEvent(new UserAddSuccessEvent(this, user));
        return user;
    }

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

2. 添加用户成功事件

package com.shg.listener.event;

import com.shg.beans.User;
import org.springframework.context.ApplicationEvent;

public class UserAddSuccessEvent extends ApplicationEvent {
    
    private final User user;
    public UserAddSuccessEvent(Object source, User user) {
        super(source);
        this.user = user;
    }

    public User getUser() {
        return user;
    }
}

3. 添加用户成功事件监听器

package com.shg.listener;

import com.shg.listener.event.UserAddFailEvent;
import com.shg.listener.event.UserAddSuccessEvent;
import lombok.extern.slf4j.Slf4j;
import org.springframework.context.event.EventListener;
import org.springframework.stereotype.Component;

// 实现ApplicationListener接口的方式
// @Slf4j
// @Component
// public class UserAddListener implements ApplicationListener<UserAddSuccessEvent> {
//     @Override
//     public void onApplicationEvent(UserAddSuccessEvent event) {
//         log.info("创建用户:{}, 成功,已发送短信给管理员...", event.getUser());
//     }
// }


// 使用@EventListener的方式
@Slf4j
@Component
public class UserAddListener {
    
    @EventListener(value = {UserAddSuccessEvent.class})
    public void listenerUserAddSuccessEvent(UserAddSuccessEvent event) {
        log.info("创建用户:{}, 成功,已发送短信给管理员...", event.getUser());
    }
}

4. 运行结果

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

vue3+electron项目搭建,遇到的坑

我主要是写后端,所以对前端的vue啊vue-cli只是知其然,不知其所以然 这样也导致了我在开发前端时候遇到了很多的坑 第一个坑, vue2升级vue3始终升级不成功 第二个坑, vue add electron-builder一直卡进度,进度条走完就是不出提示succes 第一个坑的解决办法: 按照网上说的升级v…

DNS正向解析与反向解析实验

正向解析 安装bind软件 [rootlocalhost ~]# dnf install bind bind-utils -y修改主配置文件/etc/named.conf [rootlocalhost ~]# vim /etc/named.conf重启DNS服务&#xff08;named&#xff09; [rootlocalhost ~]# systemctl restart named编辑数据配置文件。在/var/named…

AI绘画Stable Diffusion【图生图教程】:图片高清修复的三种方案详解,你一定能用上!(附资料)

大家好&#xff0c;我是画画的小强 今天给大家分享一下用AI绘画Stable Diffusion 进行 高清修复&#xff08;Hi-Res Fix&#xff09;&#xff0c;这是用于提升图像分辨率和细节的技术。在生成图像时&#xff0c;初始的低分辨率图像会通过放大算法和细节增强技术被转换为高分辨…

Linux运维:mysql主从复制原理及实验

当一台数据库服务器出现负载的情况下&#xff0c;需要扩展服务器服务器性能扩展方式有向上扩展&#xff0c;垂直扩展。向外扩展&#xff0c;横向扩展。通俗的讲垂直扩展是将一台服务器扩展为性能更强的服务器。横向扩展是增加几台服务器。 主从复制好比存了1000块钱在主上&…

Flutter-实现双向PK进度条

如何实现一个双向PK进度条 在Flutter应用中&#xff0c;进度条是一个非常常见的组件。而双向PK进度条则能够展示两个对立的数值&#xff0c;如对战中的双方得分对比等。本文将介绍如何实现一个具有双向PK效果的进度条&#xff0c;并支持竖直和斜角两种过渡效果。 1. 需求 我…

仪器校准后出了校准证书后,是不是就代表仪器合格了?

仪器校准是一门技术活&#xff0c;对于从事生产制造的企业而言&#xff0c;是不可或缺的一环&#xff0c;因为这与产品质量密切相关。所以&#xff0c;了解仪器校准的相关知识也变得尤为重要。 在拿到校准证书后&#xff0c;是不是说明仪器合格了&#xff1f;相信不少企业品管人…

苍穹外卖--sky-take-out(五)前端

大部分笔记都是写在语雀的&#xff0c;这是一次性从本人语雀复制过来的&#xff0c;可能结构有些错乱 基础创建 环境要求 node.js npm Vue CLI 创建前端工程 使用vue ui命令创建 项目结构 启动项目 打开命令行窗口 快捷键ctrlj 或者 运行 输入&#xff1a;npm run ser…

基于单片机的多功能电子时钟的设计

摘要&#xff1a;提出了一种基于单片机的多功能电子时钟的设计方法&#xff0c;以 AT89C52单片机作为系统的主控芯片&#xff0c;采用DS1302作为时钟控制芯片&#xff0c;实现日期时钟显示并且提供精准定时的功能。此外&#xff0c;还可经由DHT22所构成的温湿度传感电路&#x…

Chair Footrest Protective Cover

Chair Footrest Protective Cover 万能通用型椅子脚垫保护套凳子耐磨硅胶加厚垫桌椅脚垫防滑静音套

【学术会议征稿】2024年工业自动化与机器人国际学术会议(IAR 2024)

2024年工业自动化与机器人国际学术会议&#xff08;IAR 2024&#xff09; 2024 International Conference on Industrial Automation and Robotics 2024年工业自动化与机器人国际学术会议&#xff08;IAR 2024&#xff09;将于2024年10月18-20日在新加坡隆重召开。会议将围绕…

ConcurrentHashMap是如何保证线程安全的-put方法简要分析

简介 ConcurrentHashMap 是 Java 中并发编程中常用的线程安全的哈希表&#xff08;HashMap&#xff09;实现。它具有以下几个显著的特点和优点&#xff0c;适合在特定的并发场景中使用&#xff1a; 线程安全性&#xff1a; ConcurrentHashMap 提供了并发访问的线程安全保证&am…

Keras实战之图像分类识别

文章目录 整体流程数据加载与预处理搭建网络模型优化网络模型学习率Drop-out操作权重初始化方法对比正则化加载模型进行测试 实战&#xff1a;利用Keras框架搭建神经网络模型实现基本图像分类识别&#xff0c;使用自己的数据集进行训练测试。 问&#xff1a;为什么选择Keras&am…

RedHat9 | Zabbix-Server监控服务部署

系统版本以及软件版本 使用的系统版本&#xff1a; Red Hat Enterprise Linux release 9.2 软件版本&#xff1a; zabbix-release-7.0-3.el9.noarchzabbix-web-7.0.0-release1.el9.noarchzabbix-web-mysql-7.0.0-release1.el9.noarchzabbix-web-deps-7.0.0-release1.el9.noar…

基于Android Studio订餐管理项目

目录 项目介绍 图片展示 运行环境 获取方式 项目介绍 能够实现登录&#xff0c;注册、首页、订餐、购物车&#xff0c;我的。 用户注册后&#xff0c;登陆客户端即可完成订餐、浏览菜谱等功能&#xff0c;点餐&#xff0c;加入购物车&#xff0c;结算&#xff0c;以及删减…

【电商纯干货分享】干货速看!电商数据集数据API接口数据分析大全!

数据分析——深入探索中小企业数字化转型&#xff0c;专注提供各行业数据分析干货、分析技巧、工具推荐以及各类超实用分析模板&#xff0c;为钻研于数据分析的朋友们加油充电。 公共参数 名称类型必须描述keyString是调用key&#xff08;必须以GET方式拼接在URL中&#xff09…

Unity编辑器扩展之Inspector面板扩展

内容将会持续更新&#xff0c;有错误的地方欢迎指正&#xff0c;谢谢! Unity编辑器扩展之Inspector面板扩展 TechX 坚持将创新的科技带给世界&#xff01; 拥有更好的学习体验 —— 不断努力&#xff0c;不断进步&#xff0c;不断探索 TechX —— 心探索、心进取&#xff…

Java--Super

1.super调用父类的构造方法&#xff0c;必须在构造方法的第一个 2.super必须只能出现在子类的方法或者构造方法中 3.super和this不能同时调用构造该方法 和this差别 1.代表的对象不同 this&#xff08;&#xff09;&#xff1a;代指本身调用者这个对象 super&#xff08;&a…

Docker-文件分层与数据卷挂载详解(附案例)

文章目录 文件分层数据卷挂载的含义数据卷挂载实践数据卷挂载案例数据卷挂载方式数据卷常用命令容器间数据共享 更多相关内容可查看 文件分层 例&#xff1a;拉取mysql5.7的镜像&#xff0c;在继续拉取mysql5.8的镜像&#xff0c;会出现一部分文件已存在的现象 这种分层技术 是…

同花顺问财选股,使用自然语言的形式调接口选股

http形式的接口调用问财接口&#xff1a;https://stockapi.com.cn/v1/base/xuangu?strategy创业板&#xff0c;竞价涨幅大于1&#xff0c;竞价量比大于1 代码中调用该接口调试数据。

cmake编译源码教程(一)

1、介绍 本次博客介绍使用cmake编译平面点云分割的源代码,其对室内点云以及TLS点云中平面结构进行分割,分割效果如下: 2、编译过程 2.1 源代码下载 首先,下载源代码,如下所示,在该文件夹下新建一个build文件夹,用于后续生成sln工程。 同时,由于该库依赖open…