SpringBoot下使用自定义监听事件

这篇具有很好参考价值的文章主要介绍了SpringBoot下使用自定义监听事件。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

事件机制是Spring的一个功能,目前我们使用了SpringBoot框架,所以记录下事件机制在SpringBoot框架下的使用,同时实现异步处理。事件机制其实就是使用了观察者模式(发布-订阅模式)。

Spring的事件机制经过如下流程:

  • 1、自定义事件,继承org.springframework.context.ApplicationEvent抽象类
  • 2、定义事件监听器,实现org.springframework.context.ApplicationListener接口
  • 3、在Spring容器中发布事件

SpringBoot的实例程序

实现一个保存用户的时候,向用户提供的邮箱发送一封邮件的功能,同时采用异步处理。

自定义事件
import org.springframework.context.ApplicationEvent;

public class EmailEvent extends ApplicationEvent {

	private static final long serialVersionUID = 3733891603598996786L;

	private String emailAddress;

	public EmailEvent(String emailAddress) {
		super(emailAddress);
		this.emailAddress = emailAddress;
	}

	public String getEmailAddress() {
		return emailAddress;
	}

	public void setEmailAddress(String emailAddress) {
		this.emailAddress = emailAddress;
	}
}
定义事件监听器
import java.util.concurrent.TimeUnit;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.context.ApplicationListener;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Component;

@Component
public class EmailEventListener implements ApplicationListener<EmailEvent> {

	private static Logger log = LoggerFactory.getLogger(EmailEventListener.class);

	// 异步处理
	@Async
	@Override
	public void onApplicationEvent(EmailEvent event) {
		log.info("监听到事件--邮箱地址:" + event.getEmailAddress());

		//模拟处理的耗时3s
		try {
			TimeUnit.SECONDS.sleep(3);
		} catch (InterruptedException e) {
			e.printStackTrace();
		}

		log.info("事件处理完成");
	}

}
发布事件
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext;
import org.springframework.stereotype.Component;

@Component
public class EmailEventPublish {

	@Autowired
	private ApplicationContext applicationContext;

	public void publishEvent(String emailAddress) {
		EmailEvent event = new EmailEvent(emailAddress);
		applicationContext.publishEvent(event);
	}

}
调用事件
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

import com.example.demo.event.EmailEventPublish;


@RestController
public class EventController {
	private static Logger log = LoggerFactory.getLogger(EventController.class);

	@Autowired
	private EmailEventPublish emailEventPublish;

	@RequestMapping("/event")
	public void publishEvent(@RequestParam String emailAddress) {
		// 发布事件 -- 采用异步处理
		emailEventPublish.publishEvent(emailAddress);

		// 正常该语句先执行
		log.info("Controller业务处理");
	}
}
结果

访问如下地址

http://localhost:8080/event?emailAddress=plf@163.com

结果为

2023-08-04 21:21:14.338  INFO 6400 --- [nio-8080-exec-1] o.a.c.c.C.[Tomcat].[localhost].[/]       : Initializing Spring FrameworkServlet 'dispatcherServlet'
2023-08-04 21:21:14.338  INFO 6400 --- [nio-8080-exec-1] o.s.web.servlet.DispatcherServlet        : FrameworkServlet 'dispatcherServlet': initialization started
2023-08-04 21:21:14.370  INFO 6400 --- [nio-8080-exec-1] o.s.web.servlet.DispatcherServlet        : FrameworkServlet 'dispatcherServlet': initialization completed in 32 ms
2023-08-04 21:21:14.429  INFO 6400 --- [nio-8080-exec-1] .s.a.AnnotationAsyncExecutionInterceptor : No task executor bean found for async processing: no bean of type TaskExecutor and no bean named 'taskExecutor' either
2023-08-04 21:21:14.534  INFO 6400 --- [nio-8080-exec-1] c.e.demo.controller.EventController      : Controller业务处理
2023-08-04 21:21:14.535  INFO 6400 --- [cTaskExecutor-1] c.example.demo.event.EmailEventListener  : 监听到事件--邮箱地址:plf@163.com
2023-08-04 21:21:17.536  INFO 6400 --- [cTaskExecutor-1] c.example.demo.event.EmailEventListener  : 事件处理完成

上述结果可知是实现了异步处理,先打印了事件之后的程序,等时间到再执行监听程序的代码。

实现异步处理就是在监听事件执行业务代码的方法上添加@Async注解,同时在启动类上添加@EnableAsync即可。

上面的日志还提到了TaskExecutor,这是如果有自定义的线程池就会去调用,如果没有就用默认的。我们也可以自己定义一个TaskExecutor

import org.springframework.aop.interceptor.AsyncUncaughtExceptionHandler;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.lang.Nullable;
import org.springframework.scheduling.annotation.AsyncConfigurer;
import org.springframework.scheduling.annotation.EnableAsync;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;

import java.util.concurrent.Executor;
import java.util.concurrent.ThreadPoolExecutor;

@EnableAsync
@Configuration
public class ThreadPool implements AsyncConfigurer {
	@Nullable
	@Override
	@Bean("taskExecutor")
	public Executor getAsyncExecutor() {
		ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
		// 线程池创建时候初始化的线程数
		executor.setCorePoolSize(10);
		// 线程池最大的线程数,只有在缓冲队列满了之后才会申请超过核心线程数的线程
		executor.setMaxPoolSize(20);
		// 用来缓冲执行任务的队列
		executor.setQueueCapacity(200);
		// 允许线程的空闲时间60秒
		executor.setKeepAliveSeconds(60);
		// 线程池名的前缀
		executor.setThreadNamePrefix("taskExecutor-");
		// 线程池对拒绝任务的处理策略
		executor.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy());
		executor.initialize();
		return executor;
	}

	@Nullable
	@Override
	public AsyncUncaughtExceptionHandler getAsyncUncaughtExceptionHandler() {
		return null;
	}
}

结果

2023-08-04 21:27:36.507  INFO 7848 --- [nio-8080-exec-2] o.a.c.c.C.[Tomcat].[localhost].[/]       : Initializing Spring FrameworkServlet 'dispatcherServlet'
2023-08-04 21:27:36.507  INFO 7848 --- [nio-8080-exec-2] o.s.web.servlet.DispatcherServlet        : FrameworkServlet 'dispatcherServlet': initialization started
2023-08-04 21:27:36.537  INFO 7848 --- [nio-8080-exec-2] o.s.web.servlet.DispatcherServlet        : FrameworkServlet 'dispatcherServlet': initialization completed in 30 ms
2023-08-04 21:27:36.757  INFO 7848 --- [nio-8080-exec-2] c.e.demo.controller.EventController      : Controller业务处理
2023-08-04 21:27:36.757  INFO 7848 --- [ taskExecutor-1] c.example.demo.event.EmailEventListener  : 监听到事件--邮箱地址:plf@163.com
2023-08-04 21:27:39.757  INFO 7848 --- [ taskExecutor-1] c.example.demo.event.EmailEventListener  : 事件处理完成

可知是使用我们定义的线程池[ taskExecutor-1]

总结

Spring的事件机制是一个很实用的一个功能,在监听和异步处理相关的功能比较适合。文章来源地址https://www.toymoban.com/news/detail-628296.html

到了这里,关于SpringBoot下使用自定义监听事件的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • Spring事件监听机制使用和原理解析

    你好,我是刘牌! 好久没有更新Spring了,今天来分享一下Spring的事件监听机制,之前分享过一篇Spring监听机制的使用,今天从原理上进行解析,Spring的监听机制基于观察者模式,就是就是我们所说的发布订阅模式,这种模式可以在一定程度上实现代码的解耦,如果想要实现系

    2024年02月08日
    浏览(32)
  • Java-Spring Boot 集成海康威视明眸门禁 布防|报警|回调|获取事件|查询用户信息

    最近做门禁的集成,突然感觉海康这个东西挺有意思的,于是记录一下。 好了废话不多说,开始上环境、代码 本集成是海康-设备网络集成(以人为中心) 环境:windows 开发工具:IDEA JDK版本:JDK-11.0.12 海康jar包:怎么引入都行(本地引入、maven上传到私服)           

    2024年04月15日
    浏览(83)
  • 【Spring | 事件监听详解】

    上篇 Spring 事件监听概述 对 Spring 事件监听的机制有了个基本的了解。 本篇来详细的解读下Spring 的 事件监听机制 。    ApplicationEvent 最重要的子类是 ApplicationContextEvent 抽象类, ApplicationContextEvent 是spring容器Context生命周期事件的基类。 ApplicationContextEvent 的有四个子类,如

    2024年02月12日
    浏览(27)
  • Spring事件监听源码解析

    spring事件监听机制离不开容器IOC特性提供的支持,比如容器会自动创建事件发布器,自动识别用户注册的监听器并进行管理,在特定的事件发布后会找到对应的事件监听器并对其监听方法进行回调。Spring帮助用户屏蔽了关于事件监听机制背后的很多细节,使用户可以专注于业

    2024年02月12日
    浏览(32)
  • 微信小程序 自定义全局事件监听实现

    一般app页面都需要关联刷新,比如登录后刷新登录前页面,故此,需要一个全局事件监听类,怎么实现呢? 根目录创建文件夹utils,新建文件eventBus.js(致敬java平台的EventBus),码入以下代码: 主要就是newKey、on、off、post方法,分别是创建key、开始监听、结束监听、发出事件

    2024年02月11日
    浏览(37)
  • 【Java项目】使用Nacos实现动态线程池技术以及Nacos配置文件更新监听事件

    真诚的希望能给我项目一个stars!!! 项目源码 项目视频演示 线程池(Thread Pool)是一种基于池化思想管理线程的工具,经常出现在多线程服务器中,如Tomcat。 线程过多会带来额外的开销,其中包括创建销毁线程的开销、调度线程的开销等等,同时也降低了计算机的整体性

    2024年02月09日
    浏览(26)
  • Springboot事件监听

    Springboot事件监听中主要有以下对象: 1、事件(event)可以封装和传递监听器中要处理的参数,如对象或字符串,并作为监听器中监听的目标。 2、监听器(listener)具体根据事件发生的业务处理模块,这里可以接收处理事件中封装的对象或字符串。 3、事件发布者(publisher)

    2024年02月08日
    浏览(27)
  • uniapp下拉刷新+数据缓存+自定义头部+事件监听注册

    pages.json 设置对应页面 enablePullDownRefresh 属性,激活下拉。 在 js 中定义 onPullDownRefresh 处理函数(和 onLoad 等生命周期函数同级),监听该页面用户下拉刷新事件。 需要在 pages.json 里,找到的当前页面的 pages 节点,并在style选项中开启 enablePullDownRefresh 当处理完数据刷新后,

    2024年02月02日
    浏览(33)
  • Java 框架面试题-Spring Boot自定义配置与自动配置共存

    Spring Boot 是一个快速开发框架,可以简化 Spring 应用程序的开发,其中自定义配置是其中一个非常重要的特性。 在 Spring Boot 中,自定义配置允许开发者以自己的方式来配置应用程序。自定义配置可以用于覆盖默认配置,也可以用于添加新的配置项。本文将详细介绍 java框架面

    2023年04月11日
    浏览(37)
  • vue3基础(五)watch(浅监听及深度监听),鼠标及键盘修饰符,v-model,对象写法,class使用数组,字符串模版,自定义组件标签上添加事件无效,使用data时用别名替代,solt输出内容

    监听中的 方法名 与 需要监听的 变量名 一致 如果没有(例如aa), 不会报错 ,但监听不到 所以上图会 输出1 ,而不会输出2 newValue改变后的值,oldValue改变前的值 watch 可以监听 computed 计算属性中的方法,变量等等 点击go按钮,调用change方法修改kk的值,computed中有kk,所以

    2024年02月15日
    浏览(43)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包