Java:SpringBoot实现ApplicationEvent事件的监听和发布
通过发布订阅模式实现数据的异步处理,比如异步处理邮件发送
新建SpringBoot项目
项目结构
.
├── pom.xml
└── src└── main├── java│ └── com│ └── example│ └── demo│ ├── Application.java│ ├── config│ │ └── TaskPoolConfig.java│ ├── controller│ │ └── IndexController.java│ ├── entity│ │ └── EmailDto.java│ ├── event│ │ └── SendEmailEvent.java│ ├── listener│ │ └── SendEmailListener.java│ └── service│ ├── SendEmailService.java│ └── impl│ └── SendEmailServiceImpl.java└── resources├── application.yml├── static└── templates
pom.xml
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd"><modelVersion>4.0.0</modelVersion><parent><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-parent</artifactId><version>2.7.7</version><relativePath/> <!-- lookup parent from repository --></parent><groupId>com.example</groupId><artifactId>demo</artifactId><version>0.0.1-SNAPSHOT</version><name>demo</name><description>Demo project for Spring Boot</description><properties><java.version>1.8</java.version></properties><dependencies><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-devtools</artifactId><scope>runtime</scope><optional>true</optional></dependency><dependency><groupId>org.projectlombok</groupId><artifactId>lombok</artifactId><optional>true</optional></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-test</artifactId><scope>test</scope></dependency></dependencies><build><plugins><plugin><groupId>org.springframework.boot</groupId><artifactId>spring-boot-maven-plugin</artifactId><configuration><excludes><exclude><groupId>org.projectlombok</groupId><artifactId>lombok</artifactId></exclude></excludes></configuration></plugin></plugins></build></project>
Application.java
package com.example.demo;import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;@SpringBootApplication
public class Application {public static void main(String[] args) {SpringApplication.run(Application.class, args);}
}
TaskPoolConfig.java
package com.example.demo.config;import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.scheduling.annotation.EnableAsync;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;import java.util.concurrent.Executor;/*** 线程池参数配置**/
@EnableAsync
@Configuration
public class TaskPoolConfig {/*** 自定义线程池**/@Beanpublic Executor taskExecutor() {//返回可用处理器的Java虚拟机的数量 12int i = Runtime.getRuntime().availableProcessors();System.out.println("系统最大线程数 : " + i);ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();//核心线程池大小executor.setCorePoolSize(16);//最大线程数executor.setMaxPoolSize(20);//配置队列容量,默认值为Integer.MAX_VALUEexecutor.setQueueCapacity(99999);//活跃时间executor.setKeepAliveSeconds(60);//线程名字前缀executor.setThreadNamePrefix("asyncServiceExecutor -");//设置此执行程序应该在关闭时阻止的最大秒数,以便在容器的其余部分继续关闭之前等待剩余的任务完成他们的执行executor.setAwaitTerminationSeconds(60);//等待所有的任务结束后再关闭线程池executor.setWaitForTasksToCompleteOnShutdown(true);return executor;}
}
EmailDto.java
package com.example.demo.entity;import lombok.Data;@Data
public class EmailDto {private String email;private String subject;private String content;
}
SendEmailEvent.java
package com.example.demo.event;import com.example.demo.entity.EmailDto;
import org.springframework.context.ApplicationEvent;/*** 自定义事件*/
public class SendEmailEvent extends ApplicationEvent {private EmailDto emailDto;public SendEmailEvent(EmailDto emailDto) {super(emailDto);this.emailDto = emailDto;}public EmailDto getEmailDto() {return this.emailDto;}
}
SendEmailListener.java
package com.example.demo.listener;import com.example.demo.entity.EmailDto;
import com.example.demo.event.SendEmailEvent;
import com.example.demo.service.SendEmailService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationListener;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Component;/*** 事件监听器*/
@Component
public class SendEmailListener implements ApplicationListener<SendEmailEvent> {@Autowiredprivate SendEmailService sendEmailService;@Async@Overridepublic void onApplicationEvent(SendEmailEvent event) {EmailDto emailDto = event.getEmailDto();this.sendEmailService.sendEmail(emailDto);}
}
SendEmailService.java
package com.example.demo.service;import com.example.demo.entity.EmailDto;public interface SendEmailService {void sendEmail(EmailDto emailDto);
}
SendEmailServiceImpl.java
package com.example.demo.service.impl;import com.example.demo.entity.EmailDto;
import com.example.demo.service.SendEmailService;
import org.springframework.stereotype.Service;@Service
public class SendEmailServiceImpl implements SendEmailService {@Overridepublic void sendEmail(EmailDto emailDto) {try {// 模拟耗时3秒Thread.sleep(3 * 1000);} catch (Exception e) {System.out.println("Email发送异常");}System.out.println("Email发送成功 " + emailDto);}
}
IndexController.java
package com.example.demo.controller;import com.example.demo.entity.EmailDto;
import com.example.demo.event.SendEmailEvent;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationEventPublisher;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;@RestController
public class IndexController {@Autowiredprivate ApplicationEventPublisher publisher;@GetMapping("/sendEmail")public String sendEmail() {EmailDto emailDto = new EmailDto();emailDto.setEmail("tom@qq.com");emailDto.setSubject("邮件标题");emailDto.setContent("邮件内容");// 发布事件publisher.publishEvent(new SendEmailEvent(emailDto));return "success";}
}
参考
- Spring事件机制 ApplicationEventPublisher
相关文章:
Java:SpringBoot实现ApplicationEvent事件的监听和发布
通过发布订阅模式实现数据的异步处理,比如异步处理邮件发送 新建SpringBoot项目 项目结构 . ├── pom.xml └── src└── main├── java│ └── com│ └── example│ └── demo│ ├── Application.java│ …...
星戈瑞-Sulfo-Cyanine3 azide?磺酸基-Cy3-N3叠氮基水溶性染料
Sulfo-Cyanine3 azide? 品牌:星戈瑞 CAS号:2055138-89-9 外观: 暗红色晶体 分子量:720.83 分子式:C34H45N6NaO8S2 纯度:95% 储藏条件:-20C 下避光保存 Sulfo-Cyanine3 azide 是一种…...
十大经典排序算法(下)
🍓个人主页:bit.. 🍒系列专栏:Linux(Ubuntu)入门必看 C语言刷题 数据结构与算法 HTML和CSS3 目录 1.6 快速排序 1. 算法步骤 2. 动图演示 3.代码实现 1.7 堆排序 1. 算法步骤 2. 动图演示 3. 代码实现 1.8 计数排…...
网络协议分析期末复习(四)
目录 0.前言 1.IP层对改善TCP性能支持的机制 2.TCP防止半开放连接的机制 3.TCP协议中强推位(P)和紧急位(U)的用法 4.TCP的流量控制和拥塞控制的异同点 异: (1)两者的特点不同:…...
Matlab对图像和视频的简单处理(图像视频文件读取和输出,转灰度图,取指定帧的图像)
文章目录1.图像文件的读取2.图像效果展示3.将彩色图转换为灰度图4.视频文件的读取5.读取视频中指定帧的图像6.图片文件的报错1.图像文件的读取 语法介绍: A imread(filename) A imread(filename, fmt)参数介绍: filename:要读取的图像文…...
ArrayList源码分析
ArrayList源码分析目标:一、 ArrayList的简介二、ArrayList原理分析2.1 ArrayList的数据结构源码分析2.2 ArrayList默认容量&最大容量2.3 为什么ArrayList查询快,增删慢?2.4 ArrayList初始化容量1、创建ArrayList对象分析:无参数2、创建A…...
SpringBoot IOC、DI、@Autowired、@Resource、作用域
一、初识Spring1.1 Spring是什么Spring是一个轻量级Java开发框架,目的是为了解决企业级应用开发的业务逻辑层和其他各层的耦合问题。它是一个分层的开源框架,为开发Java应用程序提供全面的基础架构支持。Spring负责基础架构,Java开发者可以专…...
链表相关oj题
1.Leetcode203 移除链表元素 解题思路:从头节点开始进行元素删除,每删除一个元素,需要重新链接节点 struct ListNode* removeElements(struct ListNode* head, int val){struct ListNode*dummyheadmalloc(sizeof(struct ListNode));dummyhea…...
【Linux】操作系统(Operator System)
操作系统(Operator System )一、操作系统的概念二、操作系统的作用三、系统调用和库函数一、操作系统的概念 操作系统是一组控制和管理计算机软硬件资源,为用户提供便捷使用的计算机程序的集合,是配置在计算机硬件系统上的第一层…...
机器学习自学笔记——感知机
感知机预备知识 神经元 感知机算法最初是由科学家从脑细胞的神经凸起联想而来。如下图,我们拥有三个初始xxx值,x1,x2,x0x_1,x_2,x_0x1,x2,x0。其中x01x_01x01为一个初始的常量,专业上称作“偏置”。每个xxx的值都会乘上一个权重…...
C++ Primer第五版_第三章习题答案(21~30)
文章目录练习3.21练习3.22练习3.23练习3.24练习3.25练习3.26练习3.27练习3.28练习3.29练习3.30练习3.21 请使用迭代器重做3.3.3节的第一个练习。 #include <vector> #include <iterator> #include <string> #include <iostream>using std::vector; usi…...
colmap+openmvs进行三维重建流程全记录
window下的colmapopenmvs进行三维重建流程全记录 1.colmap安装与配置 可参考:https://blog.csdn.net/weixin_44153180/article/details/129334018?spm1001.2014.3001.5501 2.openmvs安装与配置 可参考:https://blog.csdn.net/rdw1246010462/article…...
yolov8命令行运行参数详解
序言 整理来自yolov8官方文档常用的一些命令行参数,官方文档YOLOv8 Docs yolov8命令行的统一运行格式为: yolo TASK MODE ARGS其中主要是三部分传参: TASK(可选) 是[detect、segment、classification]中的一个。如果没有显式传递…...
分布式锁简介
Redis因为单进程、性能高常被用于分布式锁;锁在程序中作用是同步工具,保证共享资源在同一时刻只能被一个线程访问。 Java中经常用的锁synchronized、Lock,但是Java的锁智能保证单机的时候有效,分布式集群环境就无能为力了…...
【嵌入式Linux学习笔记】Linux驱动开发
Linux系统构建完成后,就可以基于该环境方便地进行开发了,相关的开发流程与MCU类似,但是引入了设备树的概念,编写应用代码要相对复杂一点。但是省去了很多配置工作。 学习视频地址:【正点原子】STM32MP157开发板 字符…...
2023年中国高校计算机大赛-团队程序设计天梯赛(GPLT)上海理工大学校内选拔赛(同步赛)(H题)(线段树)
又到了万物复苏的季节,家乡的苹果树结果了。像往常一样小龙同学被叫回家摘苹果。 假设需要采摘的一棵树上当前有a颗苹果,那么小龙会采摘⌈a/3⌉颗苹果,其中⌈x⌉表示不小于x的最小整数。 但是,为了可持续发展,若a小于1…...
Linux内核Thermal框架详解十三、Thermal Governor(3)
接前一篇文章Linux内核Thermal框架详解十二、Thermal Governor(2) 二、具体温控策略 上一篇文章介绍并详细分析了bang_bang governor的源码。本文介绍第2种温控策略:fair_share。 2. fair_share fair_share governor总的策略是频率档位⽐较…...
TikTok品牌出海创世纪(二)
目录 1.推荐算法打造王者品牌 2.品牌聚焦海外Z群体 3.持续扩展应用场景 加速品牌全球化传播 品牌聚焦海外Z群体 “这个地球上,三分之二的人都在用Facebook“,这是对Facebook曾经统治地位最直观的描述。 但如今,这家全球社交媒体巨头的光环正…...
iOS中SDK开发 -- cocoapods库创建
在iOS项目中,经常使用cocoadpods来进行依赖管理以及三方库引入等。引入的三方库一般会有几种形式:一、在Pods目录下可以直接看到源代码的开源库,如AFNetworking,Masonry等常见开源库。二、在Pods目录下拉取的项目文件只能看到对应…...
2023年了,还是没学会内卷....
先做个自我介绍:我,普本,通信工程专业,现在飞猪干软件测试,工作时长两年半。 回望疫情纪元,正好是实习 毕业这三年。要说倒霉也是真倒霉,互联网浪潮第三波尾巴也没抓住,狗屁造富神…...
chatGPT爆火,什么时候中国能有自己的“ChatGPT“
目录 引言 一、ChatGPT爆火 二、中国何时能有自己的"ChatGPT" 三、为什么openai可以做出chatGPT? 四、结论 引言 随着人工智能技术的不断发展,自然语言处理技术也逐渐成为了研究的热点之一。其中,ChatGPT作为一项领先的自然语言处理技术…...
【Matlab算法】粒子群算法求解一维非线性函数问题(附MATLAB代码)
MATLAB求解一维非线性函数问题前言正文函数实现(可视化处理)可视化结果前言 一维非线性函数是指函数的自变量和因变量都是一维实数,而且函数的形式是非线性的,也就是不符合线性函数的形式。在一维非线性函数中,自变量…...
2023 最新发布超全的 Java 面试八股文,整整 1000道面试题,太全了
作为一名优秀的程序员,技术面试都是不可避免的一个环节,一般技术面试官都会通过自己的方式去考察程序员的技术功底与基础理论知识。 2023 年的互联网行业竞争越来越严峻,面试也是越来越难,很多粉丝朋友私信希望我出一篇面试专题或…...
产品经理面经|当面试官问你还有什么问题?
相信很多产品经理在跳槽面试的时候,在面试尾声都会遇到这样的环节,面试官会问你有什么问题要问的,一般来说大家都能随时随地甩出几个问题来化解,但其实在这个环节对于应聘者来说也是一个很好的机会来展现自己的能力,甚…...
单链表的基本操作
目录 一.链表的基本概念和结构 二.链表的分类 三.单链表的基本操作 1.创建一个节点 2.打印 3.尾插 4.头插 5.尾删 6.头删 7.查找 8.指定位置插入 9.指定位置删除 10.销毁 一.链表的基本概念和结构 概念:链表是一种物理存储结构上非连续、非顺序的存储结…...
【微信小程序-原生开发】系列教程目录(已完结)
01-注册登录账号,获取 AppID、下载安装开发工具、创建项目、上传体验 https://sunshinehu.blog.csdn.net/article/details/128663679 02-添加全局页面配置、页面、底部导航 https://sunshinehu.blog.csdn.net/article/details/128705866 03-自定义底部导航&#x…...
JavaEE--Thread 类的基本用法(不看你会后悔的嘿嘿)
Thread类是JVM用来管理线程的一个类,换句话说,每个线程都唯一对应着一个Thread对象. 因此,认识和掌握Thread类弥足重要. 本文将从 线程创建线程中断线程等待线程休眠获取线程实例 等方面来进行具体说明. 1)线程创建 方法1:通过创建Thread类的子类并重写run () 方法 class M…...
MySQL数据库基本使用(二)-------数据库及表的增删改查及字符集修改
1.MySQL数据库的使用演示 1.1创建自己的数据库 命令格式如下(创建的数据库名称不能与已经存在的数据库重名): mysql> create database 数据库名;例如: mysql> create database atguigudb; #创建atguigudb数据库…...
互联网摸鱼日报(2023-03-17)
互联网摸鱼日报(2023-03-17) InfoQ 热门话题 开源新生代的成长之路:从校园到开源,需要迈过哪些挑战? 从 Clickhouse 到 Apache Doris,慧策电商 SaaS 高并发数据服务的改造实践 刚刚,百度文心…...
【前后端】低代码平台Jeecg-Boot 3.2宝塔云服务器部署流程
1 后端 部署流程 修改配置文件 更改数据库、redis的配置。 在system子模块中的target文件夹下生成 jar 包jeecg-boot-module-system-3.2.0.jar。 复制到云服务器 生成数据库 在这里插入图片描述 使用命令运行后端程序 java -jar ./jeecg-boot-module-system-3.2.0.jar宝…...
优化志愿网站/网络精准推广
作为网页设计师或前端工程师,你可能还记得曾经的那个网页大小建议:一个网页(包括HTML、CSS、Javacript、Flash和图片)尽量不要超过30KB的大小,随着互联网的日益庞大,网络带宽也在飞速发展,很多设计师已经不再考虑这条3…...
爱网度假/网站排名优化软件
旧的时间字符串-->simpledataformat1.parse(该字符串) 获得date类型 -->simpledataformat2.format(date) simpledateformat1的pattern的格式和旧的字符串相同,simpledateformat2的pattern格式和希望的相同。 比如 旧的字符串格式为 yyyy-MM-dd,希望…...
wordpress企业站教程/外链seo服务
网格照明题目描述思路模拟Python实现Java实现题目描述 网格照明 思路 模拟 维护四个计数和点的集合。四个计数分别为行计数、列计数、左对角线计数、右对角线计数,这样只需要知道查询点在任何计数上是否大于0,就知道它是不是被照亮了。再根据点的集合…...
澄迈网站制作/seo优化网页
对网络模型压缩有什么了解 网络模型压缩方法通常有剪枝、量化、蒸馏。 剪枝分为非结构化剪枝和结构化剪枝,非结构化剪枝指将部分不重要的参数置0,在一般的硬件设备中其实并不能加速,因为即使是0仍然要参与运算,结构化剪枝指将部分…...
宁波外贸公司为什么这么多/seo关键词排名优化如何
2019独角兽企业重金招聘Python工程师标准>>> 本文是从FISCO-BCOS的官方GitHub中的安装包进行安装的记录过程 1. Node.js环境准备 #nodejs安装 nvm curl -o- https://raw.githubusercontent.com/creationix/nvm/v0.33.11/install.sh | bash source ~/.bashrc nvm ins…...
wordpress页面过期/seo优化网站词
文章目录 零、写在前面一、概念定义1、两个集合的并2、三个集合的并二、题目描述三、算法详解四、源码剖析五、推荐专栏六、习题练习零、写在前面 这是《算法零基础100讲》 专栏打卡学习的第 29 天了。如果觉得本专栏太贵无法承受,在博主主页添加博主好友,获取 付费专栏优惠券…...