在SpringBoot中添加自定義增強SpringEvent事件組件

場景說明:在使用SpringBoot時,總是要添加一大堆自定義事件,實現ApplicationEvent,來實現事件發送。

這樣寫代碼量非常大。為了方便和避免出錯,封裝自定義的模塊,快速實現泛型中調用SpringEvent實現事件。省去配置,簡化代碼,增加多線程并發處理。

一、配置自定義注解和泛型事件
1、添加自定義注解來開啟配置

import org.springframework.context.annotation.Import;import java.lang.annotation.*;/*** 自動啟用 Spring Event事件*/
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Import({QySpringEventConfiguration.class})
@Documented
public @interface EnableQySpringEvent {
}

2、自定義配置中,設置線程池和注入配置

import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.BeanFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.event.SimpleApplicationEventMulticaster;
import org.springframework.context.support.AbstractApplicationContext;
import org.springframework.core.task.TaskExecutor;
import org.springframework.scheduling.annotation.EnableAsync;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;/*** 配置,加載EventBus事件總線*/
@Configuration
@EnableAsync // 自動開啟異步處理
@Slf4j
public class QySpringEventConfiguration {private final ApplicationContext applicationContext;@Autowiredpublic QySpringEventConfiguration(ApplicationContext applicationContext) {this.applicationContext = applicationContext;}@Beanpublic QyEventService qySpringEventService() {log.info("<<<<<<<<<<<<<<< 注入QyEventService實現自定義事件 >>>>>>>>>>>>>>>>>>");return new QySpringEventServiceImpl(applicationContext);}/*** 指定線程池,專用于事件訂閱和發布** @return*/@Bean(name = "eventTaskExecutor")public TaskExecutor eventTaskExecutor() {ThreadPoolTaskExecutor taskExecutor = new ThreadPoolTaskExecutor();taskExecutor.setThreadNamePrefix("qy-springEventTaskExecutor-");taskExecutor.setCorePoolSize(5);taskExecutor.setQueueCapacity(100);taskExecutor.setMaxPoolSize(5);taskExecutor.initialize();return taskExecutor;}/*** 為SpringEvent指定線程池* 注意beanName必須為applicationEventMulticaster;下面的源碼中你將看到** @param beanFactory* @return*/@Bean(name = AbstractApplicationContext.APPLICATION_EVENT_MULTICASTER_BEAN_NAME)public SimpleApplicationEventMulticaster eventMulticaster(BeanFactory beanFactory) {SimpleApplicationEventMulticaster eventMulticaster = new SimpleApplicationEventMulticaster(beanFactory);eventMulticaster.setTaskExecutor(eventTaskExecutor());return eventMulticaster;}}

3、定義支持泛型的事件,省去每次配置ApplicationEvent的過程

import lombok.Getter;
import lombok.Setter;
import org.springframework.context.ApplicationEvent;
import org.springframework.core.ResolvableType;
import org.springframework.core.ResolvableTypeProvider;/*** 帶泛型的多重使用器** @param <T>*/
@Setter
@Getter
public class QyEvent<T> extends ApplicationEvent implements ResolvableTypeProvider {private T data;public QyEvent(T data) {super(data);this.data = data;}public QyEvent(Object source, T data) {super(source);this.data = data;}@Overridepublic ResolvableType getResolvableType() {return ResolvableType.forClassWithGenerics(getClass(), ResolvableType.forInstance(data));}
}

4、定義發送服務

/*** Spring內部自帶的事件發布器*/
public interface QyEventService {/*** 發布事件** @param qyEvent*/<T> void publishEvent(QyEvent<T> qyEvent);}

5、服務實現類

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext;
import org.springframework.stereotype.Component;@Component
public class QySpringEventServiceImpl implements QyEventService {private final ApplicationContext applicationContext;@Autowiredpublic QySpringEventServiceImpl(ApplicationContext applicationContext) {this.applicationContext = applicationContext;}@Overridepublic <T> void publishEvent(QyEvent<T> qyEvent) {applicationContext.publishEvent(qyEvent);}
}

更多精彩內容關注我的公眾號:青塬科技。

二、在使用時
1、在入口處添加注解
@EnableQySpringEvent

2、使用時,在服務中添加

@Resource
QyEventService qyEventService;

測試發送消息內容:

IntStream.rangeClosed(0, 10).forEach(item -> {qyEventService.publishEvent(new QyEvent<>("test" + item));
});

3、添加監聽器

import lombok.extern.slf4j.Slf4j;
import org.springframework.context.event.EventListener;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Component;/*** 事件監聽處理器*/
@Component
@Slf4j
public class QyEventListener {@Async // 異步實現@EventListener // 監聽器,會自動識別類型public void onOperationLogEvent(QyEvent<String> event) {log.info("QyEvent Listener recieve message: " + event.getData());}
}

日志顯示:

2024-05-21 14:51:22.798  INFO 14757 --- [qy-springEventTaskExecutor-1] c.q.justtest.listener.QyEventListener    : QyEvent Listener recieve message: test5
2024-05-21 14:51:22.798  INFO 14757 --- [qy-springEventTaskExecutor-3] c.q.justtest.listener.QyEventListener    : QyEvent Listener recieve message: test3
2024-05-21 14:51:22.798  INFO 14757 --- [qy-springEventTaskExecutor-2] c.q.justtest.listener.QyEventListener    : QyEvent Listener recieve message: test4
2024-05-21 14:51:22.798  INFO 14757 --- [qy-springEventTaskExecutor-4] c.q.justtest.listener.QyEventListener    : QyEvent Listener recieve message: test6
2024-05-21 14:51:22.798  INFO 14757 --- [qy-springEventTaskExecutor-1] c.q.justtest.listener.QyEventListener    : QyEvent Listener recieve message: test7
2024-05-21 14:51:22.798  INFO 14757 --- [qy-springEventTaskExecutor-4] c.q.justtest.listener.QyEventListener    : QyEvent Listener recieve message: test1
2024-05-21 14:51:22.798  INFO 14757 --- [qy-springEventTaskExecutor-4] c.q.justtest.listener.QyEventListener    : QyEvent Listener recieve message: test8
2024-05-21 14:51:22.798  INFO 14757 --- [qy-springEventTaskExecutor-1] c.q.justtest.listener.QyEventListener    : QyEvent Listener recieve message: test9
2024-05-21 14:51:22.798  INFO 14757 --- [qy-springEventTaskExecutor-4] c.q.justtest.listener.QyEventListener    : QyEvent Listener recieve message: test2
2024-05-21 14:51:22.798  INFO 14757 --- [qy-springEventTaskExecutor-2] c.q.justtest.listener.QyEventListener    : QyEvent Listener recieve message: test0
2024-05-21 14:51:22.798  INFO 14757 --- [qy-springEventTaskExecutor-3] c.q.justtest.listener.QyEventListener    : QyEvent Listener recieve message: test10

可以發現已經實現多線程,并且并發打印出消息。

總結

關于多線程的內容已經說完了,但是我還想說點別的,主要想說一下我們應該學習哪些技術才能讓它更加保值。

在我看來,越偏向于業務的技術越不容易過時,為什么呢?需求在變,技術一直在變,業務也一直在迭代。前端技術的發展非常快,也涌現出很多的框架(例如 HTML4 到 HTML5 的升級,或者從jQuery 到前端三大框架的轉變),但是總歸就是兩個字:效率。

作為開發者,我們需要保持好奇心和學習熱情,不斷探索新的技術,只有這樣,我們才能在這個快速發展的時代中立于不敗之地。介紹一款程序員都應該知道的軟件JNPF快速開發平臺,很多人都嘗試用過它,它是功能的集大成者,任何信息化系統都可以基于它開發出來。

JNPF可以實現應用從創建、配置、開發、測試到發布、運維、升級等完整生命周期的管理。減少了傳統應用程序的代碼編寫量,通過圖形化、可視化的界面,以拖放組件的方式,即可快速生成應用程序的產品,大幅降低了開發企業管理類軟件的難度。

當然,我更建議大家成為一個全棧,不要把自己的定位局限于前端。

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/diannao/14487.shtml
繁體地址,請注明出處:http://hk.pswp.cn/diannao/14487.shtml
英文地址,請注明出處:http://en.pswp.cn/diannao/14487.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

Xinstall助力實現App間直接跳轉,提升用戶體驗

在移動互聯網時代&#xff0c;App已成為我們日常生活中不可或缺的一部分。然而&#xff0c;在使用各類App時&#xff0c;我們經常會遇到需要在不同App之間切換的情況&#xff0c;這時如果能夠直接跳轉&#xff0c;將會大大提升用戶體驗。而Xinstall正是這樣一款能夠幫助開發者實…

OpenCV 獲取 RTSP 攝像頭視頻流保存至本地

介紹 Java OpenCV 是一個強大的開源計算機視覺庫&#xff0c;它提供了豐富的圖像處理和分析功能&#xff0c;越來越多的應用需要使用攝像頭來獲取實時視頻流進行處理和分析。 在 Java 中使用 OpenCV 打開攝像頭的基本步驟如下&#xff1a; 確保已經安裝了OpenCV庫使用 OpenC…

Raylib 繪制自定義字體的一種套路

Raylib 繪制自定義字體是真的難搞。我的需求是程序可以加載多種自定義字體&#xff0c;英文中文的都有。 我調試了很久成功了&#xff01; 很有用的參考&#xff0c;建議先看一遍&#xff1a; 瞿華&#xff1a;raylib繪制中文內容 個人筆記&#xff5c;Raylib 的字體使用 - …

W801 實現獲取天氣情況

看了小安派&#xff08;AiPi-Eyes 天氣站&#xff09;的源碼&#xff0c;感覺用W801也可以實現。 一、部分源碼 main.c #include "wm_include.h" #include "Lcd_Driver.h"void UserMain(void) {printf("\n user task \n");Lcd_Init();Lcd_Clea…

MySQL主從復制(五):讀寫分離

一主多從架構主要應用場景&#xff1a;讀寫分離。讀寫分離的主要目標是分攤主庫的壓力。 讀寫分離架構 讀寫分離架構一 架構一結構圖&#xff1a; 這種結構模式下&#xff0c;一般會把數據庫的連接信息放在客戶端的連接層&#xff0c;由客戶端主動做負載均衡。也就是說由客戶…

RabbitMQ 消息隊列安裝及入門

市面常見消息隊列中間件對比 技術名稱吞吐量 /IO/并發時效性&#xff08;類似延遲&#xff09;消息到達時間可用性可靠性優勢應用場景activemq萬級高高高簡單易學中小型企業、項目rabbitmq萬級極高&#xff08;微秒&#xff09;高極高生態好&#xff08;基本什么語言都支持&am…

為什么MySQL推薦使用utf8mb4代替utf8?

前言 在MySQL數據庫的世界里&#xff0c;字符集的選擇直接影響著數據的存儲和檢索方式&#xff0c;尤其是對于多語言支持至關重要的應用而言。近年來&#xff0c;utf8mb4字符集逐漸成為MySQL中存儲Unicode字符的標準選擇&#xff0c;逐步取代了傳統的utf8字符集。本文將詳細探…

leetcode124 二叉樹中的最大路徑和-dp

題目 二叉樹中的 路徑 被定義為一條節點序列&#xff0c;序列中每對相鄰節點之間都存在一條邊。同一個節點在一條路徑序列中 至多出現一次 。該路徑 至少包含一個 節點&#xff0c;且不一定經過根節點。 路徑和 是路徑中各節點值的總和。 給你一個二叉樹的根節點 root &…

【Crypto】Rabbit

文章目錄 一、Rabbit解題感悟 一、Rabbit 題目提示很明顯是Rabbit加密&#xff0c;直接解 小小flag&#xff0c;拿下&#xff01; 解題感悟 提示的太明顯了

redis核心面試題二(實戰優化)

文章目錄 10. redis配置mysql實戰優化[重要]11. redis之緩存擊穿、緩存穿透、緩存雪崩12. redis實現分布式session 10. redis配置mysql實戰優化[重要] // 最初實現OverrideTransactionalpublic Product createProduct(Product product) {productRepo.saveAndFlush(product);je…

MQTT 5.0 報文解析 05:DISCONNECT

歡迎閱讀 MQTT 5.0 報文系列 的第五篇文章。在上一篇中&#xff0c;我們已經介紹了 MQTT 5.0 的 PINGREQ 和 PINGRESP 報文。現在&#xff0c;我們將介紹下一個控制報文&#xff1a;DISCONNECT。 在 MQTT 中&#xff0c;客戶端和服務端可以在斷開網絡連接前向對端發送一個 DIS…

手把手教你搭建一個花店小程序商城

如果你是一位花店店主&#xff0c;想要為你的生意搭建一個精美的小程序商城&#xff0c;以下是你將遵循的五個步驟。 步驟1&#xff1a;登錄喬拓云平臺進入后臺 首先&#xff0c;你需要登錄喬拓云平臺的后臺管理頁面。你可以在電腦或移動設備上的瀏覽器中輸入喬拓云的官方網站…

2024.5.26 機器學習周報

目錄 引言 Abstract 文獻閱讀 1、題目 2、引言 3、創新點 4、Motivation 5、naive Lite-HRNet 6、Lite-HRNet 7、實驗 深度學習 解讀SAM(Segment Anything Model) 1、SAM Task 2、SAM Model 2.1、Patch Embedding 2.2、Positiona Embedding 2.3、Transformer …

移動端適配:vw適配方案

vw (Viewport Width) 是一種長度單位&#xff0c;代表視口寬度的百分比。1vw 等于視口寬度的1%。在網頁設計和前端開發中&#xff0c;vw 單位常用于實現響應式設計和屏幕適配&#xff0c;尤其是針對不同尺寸和分辨率的移動設備。 為什么使用vw適配&#xff1f; 響應式: 使用v…

互聯網醫院開發:引領智慧醫療新時代

隨著科技的迅猛發展和互聯網的普及&#xff0c;傳統醫療模式正在迎來一場深刻的變革。互聯網醫院的崛起&#xff0c;打破了時間和空間的限制&#xff0c;為患者和醫療機構帶來了更加便捷、高效、安全的醫療服務體驗。本文將從技術角度深入探討互聯網醫院的開發&#xff0c;包括…

【openpcdet中yaml文件的DATA_AUGMENTOR學習】

提示&#xff1a;文章寫完后&#xff0c;目錄可以自動生成&#xff0c;如何生成可參考右邊的幫助文檔 文章目錄 前言一、代碼二、詳細解釋DISABLE_AUG_LISTAUG_CONFIG_LIST1. gt_sampling2. random_world_flip3. random_world_rotation4. random_world_scaling 總結 前言 提示…

多線程(八)

一、wait和notify 等待 通知 機制 和join的用途類似,多個線程之間隨機調度,引入 wait notify 就是為了能夠從應用層面上,干預到多個不同線程代碼的執行順序.( 這里說的干預,不是影響系統的線程調度策略 內核里的線程調度,仍然是無序的. 相當于是在應用程序…

Pod容器資源限制和探針

目錄 一、資源限制 1.Pod和容器的資源請求和限制 2.CPU 資源單位 案例一 案例二 二、健康檢查&#xff0c;又稱為探針&#xff08;Probe&#xff09; 1.探針的三種規則 2.Probe支持三種檢查方法 3.探測獲得的三種結果 案例一&#xff1a;exec 案例二&#xff1a;htt…

OneMO同行 心級服務:中移物聯OneMO模組助力客戶終端寒冷環境下的穩定運行

中移物聯OneMO模組以客戶為中心&#xff0c;基于中國移動心級服務要求&#xff0c;開展“OneMO同行 心級服務 標定一流”高標服務主題活動&#xff0c;升級“服務內容““服務方式”和“服務意識”&#xff0c;為行業客戶提供全新的服務體驗。 近日&#xff0c;某車載監控設備…

Hive語法學習總結

Hive SQL語法學習總結 hive參數庫操作1.創建庫2.具體案例3.庫的其他操作 表和庫的路徑演示表的操作創建表插入數據 hive參數 一 hive常用交互命令hive -e sql語句hive -f sql文件 //文件中是sql語句二 參數的設置方式一&#xff1a;在客戶端中設置參數(當次有效)set 參數名參…