SpringBoot使用自定义事件监听器的demo

news2024/11/28 10:45:13

记录一下SpringBoot自定义事件监听器的使用方法

案例源码:SpringBoot使用自定义事件监听器的demo

使用的SpringBoot2.0.x版本

<parent>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-parent</artifactId>
    <version>2.0.5.RELEASE</version>
    <relativePath/> <!-- lookup parent from repository -->
</parent>

自定义事件监听: 自定义事件 和 自定义监听两部分

自定义事件
继承自ApplicationEvent抽象类,定义自己的构造器

自定义监听
实现ApplicationListener接口,然后实现onApplicationEvent方法

首先自定义事件
ApplicationEvent抽象类
myw
实现继承,用对象方式,新建对象

DemoUser.java

package boot.example.event.events;

public class DemoUser {

    private String username;

    private String password;

    public String getUsername() {
        return username;
    }

    public void setUsername(String username) {
        this.username = username;
    }

    public String getPassword() {
        return password;
    }

    public void setPassword(String password) {
        this.password = password;
    }
}

EventDemoUser.java

package boot.example.event.events;

import org.springframework.context.ApplicationEvent;

public class EventDemoUser extends ApplicationEvent {

    private final DemoUser demoUser;

    public EventDemoUser(Object source, DemoUser demoUser) {
        super(source);
        this.demoUser = demoUser;
    }

    public DemoUser getDemoUser() {
        return demoUser;
    }
}

ApplicationListener接口
myw
自定义监听类
EventDemoUserListener.java

package boot.example.event.listener;

import boot.example.event.events.EventDemoUser;
import org.springframework.context.ApplicationListener;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Component;
import org.springframework.stereotype.Service;

//  将监听器装载入spring容器
@Component
//@Service
public class EventDemoUserListener implements ApplicationListener<EventDemoUser> {

    @Async
    @Override
    public void onApplicationEvent(EventDemoUser eventDemoUser) {
        System.out.println("自定义事件监听器(EventDemoUserListener)收到发布的消息: " + eventDemoUser.getDemoUser().getUsername());
        System.out.println("自定义事件监听器(EventDemoUserListener)收到发布的消息: " + eventDemoUser.getDemoUser().getPassword());
    }
}

我这里使用接口的方式来触发
EventDemoUserController.java

package boot.example.event.controller;

import boot.example.event.events.DemoUser;
import boot.example.event.events.EventDemo;
import boot.example.event.events.EventDemoUser;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationEventPublisher;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.annotation.Resource;

@RestController
@RequestMapping(value="/eventDemoUser")
public class EventDemoUserController {

	@Resource
	private ApplicationContext applicationContext;

	@RequestMapping(value="/test1")
	public String test1() {
		DemoUser demoUser = new DemoUser();
		demoUser.setUsername("admin");
		demoUser.setPassword("123456");

		applicationContext.publishEvent(new EventDemoUser(this, demoUser));
		return "testEventDemo";
	}

	@Resource
	private ApplicationEventPublisher applicationEventPublisher;

	@RequestMapping(value="/test2")
	public String test2() {
		DemoUser demoUser = new DemoUser();
		demoUser.setUsername("admin2");
		demoUser.setPassword("654321");

		applicationContext.publishEvent(new EventDemoUser(this, demoUser));
		return "testEventDemo";
	}

}

这里使用了两种触发方式

@Resource
private ApplicationContext applicationContext;
@Resource
private ApplicationEventPublisher applicationEventPublisher;

控制台输出查看
myw
自定义监听的几种方式

1.启动时手动向ApplicationContext中添加监听器

EventDemo.java

package boot.example.event.events;

import org.springframework.context.ApplicationEvent;

public class EventDemo extends ApplicationEvent {

    public EventDemo(Object source) {
        super(source);
    }
}

AppEventDemo.java

package boot.example.event;

import boot.example.event.listener.EventDemoListener1;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.ConfigurableApplicationContext;
import org.springframework.scheduling.annotation.EnableAsync;

@SpringBootApplication
@EnableAsync
public class AppEventDemo {

    public static void main( String[] args ) {
        ConfigurableApplicationContext context = SpringApplication.run(AppEventDemo.class, args);

        // 手动向ApplicationContext中添加监听器
        context.addApplicationListener(new EventDemoListener1());
        System.out.println( "Hello World!" );
    }

    //  事件监听,自定义事件和自定义监听器类
    //  自定义事件:继承自ApplicationEvent抽象类,定义自己的构造器
    //  自定义监听:实现ApplicationListener接口,实现onApplicationEvent方法



}

EventDemoListener1.java

package boot.example.event.listener;

import boot.example.event.events.EventDemo;
import org.springframework.context.ApplicationListener;

//  手动向ApplicationContext中添加监听器  不要@Component注解就能监听到
public class EventDemoListener1 implements ApplicationListener<EventDemo> {

    @Override
    public void onApplicationEvent(EventDemo eventDemo) {
        Object msg = eventDemo.getSource();
        System.out.println("自定义事件监听器(MyEventListener1)收到发布的消息: " + msg);
    }
}

2.使用@Component注解自动监听

EventDemoListener2.java

package boot.example.event.listener;

import boot.example.event.events.EventDemo;
import org.springframework.context.ApplicationListener;
import org.springframework.stereotype.Component;


//  将监听器装载入spring容器
@Component
public class EventDemoListener2 implements ApplicationListener<EventDemo> {
    @Override
    public void onApplicationEvent(EventDemo eventDemo) {
        Object msg = eventDemo.getSource();
        System.out.println("自定义事件监听器(MyEventListener2)收到发布的消息: " + msg);
    }
}


3.在application.properties中配置监听器,可以不用注解

EventDemoListener3.java

package boot.example.event.listener;

import boot.example.event.events.EventDemo;
import org.springframework.context.ApplicationListener;


//  在application.properties中配置监听器,可以不用注解
public class EventDemoListener3 implements ApplicationListener<EventDemo> {
    @Override
    public void onApplicationEvent(EventDemo eventDemo) {
        Object msg = eventDemo.getSource();
        System.out.println("自定义事件监听器(MyEventListener3)收到发布的消息: " + msg);
    }

}


application.properties配置

context.listener.classes=boot.example.event.listener.EventDemoListener3

4.通过@EventListener注解实现事件监听(使用最方便)

EventDemoListener4.java

package boot.example.event.listener;

import boot.example.event.events.EventDemo;
import org.springframework.context.event.EventListener;
import org.springframework.stereotype.Component;


//  通过@EventListener注解实现事件监听
@Component
public class EventDemoListener4 {
    @EventListener
    public void listener(EventDemo eventDemo) {
        Object msg = eventDemo.getSource();
        System.out.println("自定义事件监听器(MyEventListener4)收到发布的消息: " + msg);
    }

}


触发监听

EventDemoController .java

package boot.example.event.controller;

import boot.example.event.events.EventDemo;
import org.springframework.context.ApplicationContext;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.annotation.Resource;

@RestController
@RequestMapping(value="/eventDemo")
public class EventDemoController {

	@Resource
	private ApplicationContext applicationContext;

	@RequestMapping(value="/test")
	public String test() {
		applicationContext.publishEvent(new EventDemo("测试监听事件"));
		return "testEventDemo";
	}
}

控制台查看 四种方式执行默认是有先后顺序的
myw
还有一种方式 这种方式使用更方便

DemoRole.java 和 DemoUser.java

package boot.example.event.events;

public class DemoRole {

    private Integer roleId;

    private String roleName;

    public Integer getRoleId() {
        return roleId;
    }

    public void setRoleId(Integer roleId) {
        this.roleId = roleId;
    }

    public String getRoleName() {
        return roleName;
    }

    public void setRoleName(String roleName) {
        this.roleName = roleName;
    }
}

package boot.example.event.events;

public class DemoUser {

    private String username;

    private String password;

    public String getUsername() {
        return username;
    }

    public void setUsername(String username) {
        this.username = username;
    }

    public String getPassword() {
        return password;
    }

    public void setPassword(String password) {
        this.password = password;
    }
}

监听类EventDemoListenerMultiple.java

package boot.example.event.listener;


import boot.example.event.events.DemoRole;
import boot.example.event.events.DemoUser;
import org.springframework.context.event.EventListener;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Component;
import org.springframework.stereotype.Service;

@Component
//@Service
public class EventDemoListenerMultiple {

    @Async
    @EventListener(DemoUser.class)
    public void listenerDemoUser(DemoUser demoUser) {
        String name = demoUser.getUsername();
        System.out.println("listenerDemoUser---"+name);
    }

    @Async
    @EventListener(DemoRole.class)
    public void listenerDemoUser(DemoRole demoRole) {
        String name = demoRole.getRoleName();
        System.out.println("listenerDemoUser---"+name);
    }

}

监听器触发类EventDemoMultipleController.java

package boot.example.event.controller;

import boot.example.event.events.DemoRole;
import boot.example.event.events.DemoUser;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationEventPublisher;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import javax.annotation.Resource;

@RestController
@RequestMapping(value="/eventDemo")
public class EventDemoMultipleController {

	@Resource
	private ApplicationContext applicationContext;

	@RequestMapping(value="/demoUser")
	public String demoUser() {
		DemoUser demoUser = new DemoUser();
		demoUser.setUsername("admin");
		demoUser.setPassword("123456");

		applicationContext.publishEvent(demoUser);
		return "testEventDemo";
	}

	@Resource
	private ApplicationEventPublisher applicationEventPublisher;

	@RequestMapping(value="/demoRole")
	public String demoRole() {
		DemoRole demoRole = new DemoRole();
		demoRole.setRoleId(4);
		demoRole.setRoleName("角色");

		applicationContext.publishEvent(demoRole);
		return "testEventDemo";
	}

}

Servlet渐渐地淡出视野,也记录一下使用

CustomServletContextListener.java

package boot.example.event.config;

import javax.servlet.ServletContextEvent;
import javax.servlet.ServletContextListener;
import javax.servlet.annotation.WebListener;


/**
 *  servelt的监听器
 */
@WebListener
public class CustomServletContextListener implements ServletContextListener {

    @Override
    public void contextInitialized(ServletContextEvent sce) {
        //  SpringBoot WEB启动间执行一次
        System.out.println("CustomServletContextListener--contextInitialized");
    }

    @Override
    public void contextDestroyed(ServletContextEvent sce) {
        //  SpringBoot WEB销毁执行
        System.out.println("CustomServletContextListener--contextDestroyed");
    }


}

在启动类加上扫描注解

@ServletComponentScan("boot.example.event.config")

项目结构
myw

记录到此!

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

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

相关文章

【Opencv入门到项目实战】(十):项目实战|文档扫描|OCR识别

所有订阅专栏的同学可以私信博主获取源码文件 文章目录 1.引言1.1 什么是光学字符识别 (OCR)1.2 应用领域 2.项目背景介绍3.边缘检测3.1 原始图像读取3.2 预处理3.3 结果展示 3.轮廓检测4.透视变换5.OCR识别5.1 tesseract安装5.2 字符识别 1.引言 今天我们来看一个OCR相关的文…

开发工具IDEA的下载与初步使用【各种快捷键的设置,使你的开发事半功倍】

&#x1f973;&#x1f973;Welcome Huihuis Code World ! !&#x1f973;&#x1f973; 接下来看看由辉辉所写的关于IDEA的相关操作吧 目录 &#x1f973;&#x1f973;Welcome Huihuis Code World ! !&#x1f973;&#x1f973; 一.IDEA的简介以及优势 二.IDEA的下载 1.下…

释放马氏距离的力量:用 Python 探索多元数据分析

一、说明 马哈拉诺比斯距离&#xff08;Mahalanobis Distance&#xff09;是一种测量两个概率分布之间距离的方法。它是基于样本协方差矩阵的函数&#xff0c;用于评估两个向量之间的相似程度。Mahalanobis Distance考虑了数据集中各个特征之间的协方差&#xff0c;因此比欧氏距…

skynet 网络模块解析

文章目录 前言环境准备sneak peek线程数据结构会话对象&#xff1a;持有基础套接字&#xff0c;封装了套接字的基础操作。会话管理器&#xff1a;持有并管理会话池&#xff0c;给外部模块提供网络接口。 网络模块管理会话管理器的生命周期管理工作模式 总结技术点原子数据管道描…

漫话拥塞控制:BBR 是个单流模型

概要(便于检索主题)&#xff1a;单流&#xff0c;多流收敛&#xff0c;probe buffer 挤压带宽&#xff0c;maxbw-filter wnd。 我曾经经常说 BBR 是个单流模型&#xff0c;而不是多流收敛模型&#xff0c;也做过不少评论&#xff0c;最近在复听 IETF 的大会&#xff0c;在 IET…

SQL | 检索数据

1-检索数据 1.1-检索单个列 SELECT prod_name FROM Products; 上述SELECT语句从Products表中检索一个名为prod_name的列。 所要查找的列在select后面&#xff0c;from关键字指出从那个表查询数据。 输出如下&#xff1a; prod_name8 inch teddy bear12 inch teddy bear18…

linux鲁班猫代码初尝试[编译镜像][修改根文件系统重编译][修改设备树改屏幕为MIPI]

编译镜像 官方百度云盘资料:https://doc.embedfire.com/linux/rk356x/quick_start/zh/latest/quick_start/baidu_cloud/baidu_cloud.html 解压虚拟机压缩包:"鲁班猫\8-SDK源码压缩包\开发环境虚拟机镜像\ubuntu20.04.7z"后既可以用VMware打开,打开后可以看到已经有…

【前端】JQ生成二维码

提供两种方法&#xff0c;两种都是借助JQ插件生成。 所需文件&#xff1a;https://download.csdn.net/download/qq_25285531/88204985https://download.csdn.net/download/qq_25285531/88204985 方法一&#xff1a; <script type"text/javascript" src"/s…

【JavaEE基础学习打卡02】是时候了解JavaEE了

目录 前言一、为什么要学习JavaEE二、JavaEE规范介绍1.什么是规范&#xff1f;2.什么是JavaEE规范&#xff1f;3.JavaEE版本 三、JavaEE应用程序模型1.模型前置说明2.模型具体说明 总结 前言 &#x1f4dc; 本系列教程适用于JavaWeb初学者、爱好者&#xff0c;小白白。我们的天…

【刷题笔记8.11】LeetCode题目:二叉树中序遍历、前序遍历、后序遍历

LeetCode题目&#xff1a;二叉树中序遍历、前序遍历、后序遍历 题目1&#xff1a;二叉树中序遍历 &#xff08;一&#xff09;题目描述 给定一个二叉树的根节点 root &#xff0c;返回 它的 中序 遍历 。 &#xff08;二&#xff09;分析 二叉树中序遍历&#xff0c;遍历…

6-Ngnix配置反向代理

1.前提 虚拟机能连接外网 仿真http应用需在本虚拟机启用(原因&#xff1a;只有一台虚拟机做测试) http_8080和http_8081要启用&#xff08;http测试应用&#xff09; [rootcent79-2 ~]# ls -l http_* -rwxr-xr-x 1 root root 6391676 Jul 19 13:39 http_8080 -rwxr-xr-x 1 …

【C# Programming】C#第一课(自己学习的笔记)

目录 一、C# 介绍 1.1 托管代码(Manage Code ) &#xff1a; 1.2 基础类型库 (Base Class Library)&#xff1a; 1.3 程序集(Assembly)&#xff1a; 1.4 .NET 框架&#xff1a; 1.5 公共中间语言(Common Intermediate Language)&#xff0c;简称 IL。 1.6 C#编译器将源代…

RISC-V在快速发展的处理器生态系统中找到立足点

原文&#xff1a;RISC-V Finds Its Foothold in a Rapidly Evolving Processor Ecosystem 作者&#xff1a;Agam Shah 转载自&#xff1a;https://thenewstack.io/risc-v-finds-its-foothold-in-a-rapidly-evolving-processor-ecosystem/ 以下是正文 But the open source pr…

【用unity实现100个游戏之6】制作一个战旗自走棋类游戏(附源码)

文章目录 前言导入素材开始1. 设置瓦片间隙2. 放置全图瓦片3. 美化瓦片地图4. 添加树木障碍物5. 设定不同的排序图层6. 瓦片交互6. 瓦片交互优化6. 瓦片是否允许角色7. 添加角色8. 新增游戏管理脚本9. 角色移动范围逻辑10. 角色移动范围可视化11. 角色移动12. 重置瓦片颜色12. …

Spark(38):Streaming DataFrame 和 Streaming DataSet 转换

目录 0. 相关文章链接 1. 基本操作 1.1. 弱类型 api 1.2. 强类型 1.3. 直接执行 sql 2. 基于 event-time 的窗口操作 2.1. event-time 窗口理解 2.2. event-time 窗口生成规则 3. 基于 Watermark 处理延迟数据 3.1. 什么是 Watermark 机制 3.2. update 模式下使用 w…

【计算机视觉|生成对抗】条件生成对抗网络(CGAN)

本系列博文为深度学习/计算机视觉论文笔记&#xff0c;转载请注明出处 标题&#xff1a;Conditional Generative Adversarial Nets 链接&#xff1a;[1411.1784] Conditional Generative Adversarial Nets (arxiv.org) 摘要 生成对抗网络&#xff08;Generative Adversarial…

04_Hudi 集成 Spark、保存数据至Hudi、集成Hive查询、MergeInto 语句

本文来自"黑马程序员"hudi课程 4.第四章 Hudi 集成 Spark 4.1 环境准备 4.1.1 安装MySQL 5.7.31 4.1.2 安装Hive 2.1 4.1.3 安装Zookeeper 3.4.6 4.1.4 安装Kafka 2.4.1 4.2 滴滴运营分析 4.2.1 需求说明 4.2.2 环境准备 4.2.2.1 工具类SparkUtils 4.2.2.2 日期转换…

读《Flask Web开发实战》(狼书)笔记 | 第1、2章

前言 2023-8-11 以前对网站开发萌生了想法&#xff0c;又有些急于求成&#xff0c;在B站照着视频敲了一个基于flask的博客系统。但对于程序的代码难免有些囫囵吞枣&#xff0c;存在许多模糊或不太理解的地方&#xff0c;只会照葫芦画瓢。 而当自己想开发一个什么网站的时&…

限流在不同场景的最佳实践

目录导读 限流在不同场景的最佳实践1. 前言2. 为什么要限流3. 有哪些限流场景3.1 限流场景分类3.2 限流与熔断降级之间的关系3.3 非业务限流3.4 业务限流 4. 有哪些限流算法4.1 计数器限流算法4.2 漏桶限流算法4.3 令牌桶限流算法4.4 滑动时间窗限流算法4.5 限流算法选型 5. 限…

【数据结构与算法】稀疏数组

文章目录 一&#xff1a;为什么会使用稀疏数组1.1 先看一个实际的需求1.2 基本介绍1.2.1 稀疏数组的处理方法1.2.2 数组的举例说明1.2.3 应用实例1.2.4 整体思路分析二维数组转稀疏数组的思路稀疏数组转原始的二维数组的思路 二&#xff1a;代码实现2.1 创建一个原始的11*11二维…