SpringBoot事件監(jiān)聽(tīng)器@EventListener的實(shí)現(xiàn)
1.概述
- 在 Spring 框架中,@EventListener是一個(gè)用于處理應(yīng)用程序事件的注解。它提供了一種方便的方式來(lái)監(jiān)聽(tīng)和響應(yīng)各種事件,使得代碼可以基于事件驅(qū)動(dòng)的方式進(jìn)行架構(gòu)。通過(guò)@EventListener注解,可以將一個(gè)方法標(biāo)記為事件監(jiān)聽(tīng)器,當(dāng)對(duì)應(yīng)的事件被發(fā)布時(shí),該方法就會(huì)被自動(dòng)調(diào)用。
2.事件驅(qū)動(dòng)架構(gòu)基礎(chǔ)
- 事件(Event):事件是對(duì)應(yīng)用程序中某個(gè)動(dòng)作或者狀態(tài)變化的抽象表示。例如,用戶(hù)注冊(cè)成功、訂單已支付、文件上傳完成等都可以看作是事件。在Spring 中,事件通常是一個(gè)繼承自ApplicationEvent的類(lèi)。
- 事件發(fā)布者(Publisher):負(fù)責(zé)發(fā)布事件的組件。它會(huì)在特定的業(yè)務(wù)邏輯執(zhí)行過(guò)程中,創(chuàng)建并發(fā)布事件。例如,在用戶(hù)注冊(cè)服務(wù)類(lèi)中,當(dāng)用戶(hù)注冊(cè)成功后,會(huì)發(fā)布一個(gè)UserRegisteredEvent。
- 事件監(jiān)聽(tīng)器(Listener):通過(guò)@EventListener注解標(biāo)記的方法所在的類(lèi)就是事件監(jiān)聽(tīng)器。它會(huì)訂閱感興趣的事件,當(dāng)事件發(fā)布時(shí),監(jiān)聽(tīng)器中的相應(yīng)方法就會(huì)被觸發(fā),執(zhí)行自定義的邏輯,如發(fā)送歡迎郵件、更新用戶(hù)積分等。
3.使用示例
- 定義事件類(lèi):首先需要定義一個(gè)事件類(lèi),繼承自ApplicationEvent。例如,定義一個(gè)用戶(hù)注冊(cè)成功的事件類(lèi):
- 這里UserRegisteredEvent類(lèi)繼承自ApplicationEvent,并且包含了一個(gè)User對(duì)象,用于傳遞用戶(hù)相關(guān)的信息。
- 發(fā)布事件:在業(yè)務(wù)邏輯中,當(dāng)用戶(hù)注冊(cè)成功后,發(fā)布事件。假設(shè)在一個(gè)UserService類(lèi)中有一個(gè)用戶(hù)注冊(cè)方法:
import org.springframework.context.ApplicationEventPublisher;
import org.springframework.stereotype.Service;
@Service
public class UserService {
private final ApplicationEventPublisher eventPublisher;
public UserService(ApplicationEventPublisher eventPublisher) {
this.eventPublisher = eventPublisher;
}
public void registerUser(User user) {
// 實(shí)際的用戶(hù)注冊(cè)邏輯,如保存用戶(hù)信息到數(shù)據(jù)庫(kù)等
//...
// 注冊(cè)成功后發(fā)布事件
UserRegisteredEvent event = new UserRegisteredEvent(this, user);
eventPublisher.publishEvent(event);
}
}
- 這里UserService類(lèi)通過(guò)構(gòu)造函數(shù)注入了ApplicationEventPublisher,在用戶(hù)注冊(cè)成功后,創(chuàng)建UserRegisteredEvent并發(fā)布。
- 監(jiān)聽(tīng)事件:使用@EventListener注解來(lái)監(jiān)聽(tīng)事件。例如,創(chuàng)建一個(gè)監(jiān)聽(tīng)器類(lèi)來(lái)發(fā)送歡迎郵件給新注冊(cè)用戶(hù):
import org.springframework.context.event.EventListener;
import org.springframework.stereotype.Component;
@Component
public class WelcomeEmailListener {
@EventListener
public void sendWelcomeEmail(UserRegisteredEvent event) {
User user = event.getUser();
// 發(fā)送歡迎郵件的邏輯,如調(diào)用郵件發(fā)送服務(wù)
System.out.println("發(fā)送歡迎郵件給用戶(hù): " + user.getEmail());
}
}
- 在這個(gè)WelcomeEmailListener類(lèi)中,sendWelcomeEmail方法使用@EventListener注解標(biāo)記,當(dāng)UserRegisteredEvent事件被發(fā)布時(shí),該方法就會(huì)被調(diào)用,從而實(shí)現(xiàn)發(fā)送歡迎郵件的邏輯。
4.事件監(jiān)聽(tīng)器的靈活性和配置
- 監(jiān)聽(tīng)多個(gè)事件:一個(gè)@EventListener注解的方法可以監(jiān)聽(tīng)多個(gè)事件。可以通過(guò)方法參數(shù)的類(lèi)型來(lái)指定要監(jiān)聽(tīng)的事件。例如:
import org.springframework.context.event.EventListener;
import org.springframework.stereotype.Component;
@Component
public class MultipleEventListener {
@EventListener
public void handleEvents(UserRegisteredEvent userEvent, OrderPlacedEvent orderEvent) {
if (userEvent!= null) {
System.out.println("處理用戶(hù)注冊(cè)事件");
// 用戶(hù)注冊(cè)事件相關(guān)邏輯
}
if (orderEvent!= null) {
System.out.println("處理訂單放置事件");
// 訂單放置事件相關(guān)邏輯
}
}
}
- 在這個(gè)例子中,handleEvents方法可以同時(shí)監(jiān)聽(tīng)UserRegisteredEvent和OrderPlacedEvent事件,根據(jù)傳入的參數(shù)類(lèi)型來(lái)區(qū)分是哪個(gè)事件,并執(zhí)行相應(yīng)的邏輯。
- 異步監(jiān)聽(tīng)事件:可以通過(guò)配置讓事件監(jiān)聽(tīng)器以異步方式執(zhí)行,提高應(yīng)用程序的性能和響應(yīng)速度。在 Spring Boot 中,可以通過(guò)@EnableAsync注解來(lái)啟用異步支持,然后在@EventListener注解中添加async = true屬性。例如:
import org.springframework.context.annotation.Configuration;
import org.springframework.scheduling.annotation.EnableAsync;
@Configuration
@EnableAsync
public class AsyncConfig {
// 配置類(lèi)內(nèi)容
}
- 然后在監(jiān)聽(tīng)器方法中:
import org.springframework.context.event.EventListener;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Component;
@Component
public class AsyncEventListener {
@Async
@EventListener
public void handleAsyncEvent(UserRegisteredEvent event) {
// 異步執(zhí)行的邏輯,如發(fā)送短信通知等,不會(huì)阻塞主線程
System.out.println("異步處理用戶(hù)注冊(cè)事件");
}
}
5.SpringBoot內(nèi)置的監(jiān)聽(tīng)器
- Spring中內(nèi)置監(jiān)聽(tīng)器例如:ApplicationReadyEvent監(jiān)聽(tīng)器、ApplicationStartedEvent監(jiān)聽(tīng)器、ServletWebServerInitializedEvent監(jiān)聽(tīng)器等。這些監(jiān)聽(tīng)器可以通過(guò)實(shí)現(xiàn) ApplicationListenner<> 泛型接口 泛型參數(shù)必須是 ApplicationEvent本身或者子類(lèi)。
- 在這個(gè)例子中實(shí)現(xiàn)了 ApplicationReadyEvent 監(jiān)聽(tīng)器,ApplicationReadyEvent是 Spring Boot 中一個(gè)非常重要的事件。它在 Spring 應(yīng)用程序完全準(zhǔn)備好接收請(qǐng)求之后觸發(fā),這意味著所有的 Spring bean 都已經(jīng)被初始化,配置文件已經(jīng)加載,并且應(yīng)用程序上下文已經(jīng)完全刷新。
import org.springframework.boot.context.event.ApplicationReadyEvent;
import org.springframework.context.ApplicationListener;
import org.springframework.stereotype.Component;
@Component
public class ApplicationReadyEventListener implements ApplicationListener<ApplicationReadyEvent> {
@Override
public void onApplicationEvent(ApplicationReadyEvent event) {
System.out.println("應(yīng)用程序已準(zhǔn)備好,可以開(kāi)始接收請(qǐng)求啦!");
// 在這里可以進(jìn)行數(shù)據(jù)庫(kù)連接檢查、緩存預(yù)熱等操作
// 例如,這里加載一些redis緩存啦。什么什么的.......
}
}到此這篇關(guān)于SpringBoot事件監(jiān)聽(tīng)器@EventListener的實(shí)現(xiàn)的文章就介紹到這了,更多相關(guān)SpringBoot @EventListener內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
Spring Boot中使用RabbitMQ 生產(chǎn)消息和消費(fèi)消息的實(shí)例代碼
本文介紹了在SpringBoot中如何使用RabbitMQ進(jìn)行消息的生產(chǎn)和消費(fèi),詳細(xì)闡述了RabbitMQ中交換機(jī)的作用和類(lèi)型,包括直連交換機(jī)、主題交換機(jī)、扇出交換機(jī)和頭交換機(jī),并解釋了各自的消息路由機(jī)制,感興趣的朋友一起看看吧2024-10-10
Java阻塞延遲隊(duì)列DelayQueue原理及使用詳解
這篇文章主要介紹了Java阻塞延遲隊(duì)列DelayQueue原理及使用詳解,阻塞隊(duì)列是一個(gè)支持兩個(gè)附加操作的隊(duì)列,這兩個(gè)附加的操作是:在隊(duì)列為空時(shí),從隊(duì)列中獲取元素的消費(fèi)者線程會(huì)一直等待直到隊(duì)列變?yōu)榉强?需要的朋友可以參考下2023-12-12
mybatis映射文件操作存儲(chǔ)過(guò)程的實(shí)現(xiàn)
本文主要介紹了mybatis映射文件操作存儲(chǔ)過(guò)程的實(shí)現(xiàn),文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2023-03-03
使用Feign動(dòng)態(tài)設(shè)置header和原理分析
這篇文章主要介紹了使用Feign動(dòng)態(tài)設(shè)置header和原理分析,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2022-03-03
Spring?Boot?Admin?添加報(bào)警提醒和登錄驗(yàn)證功能的具體實(shí)現(xiàn)
報(bào)警提醒功能是基于郵箱實(shí)現(xiàn)的,當(dāng)然也可以使用其他的提醒功能,如釘釘或飛書(shū)機(jī)器人提醒也是可以的,但郵箱報(bào)警功能的實(shí)現(xiàn)成本最低,所以本文我們就來(lái)看郵箱的報(bào)警提醒功能的具體實(shí)現(xiàn)2022-01-01
SpringBoot @Validated注解實(shí)現(xiàn)參數(shù)分組校驗(yàn)的方法實(shí)例
這篇文章主要給大家介紹了關(guān)于SpringBoot @Validated注解實(shí)現(xiàn)參數(shù)分組校驗(yàn)的相關(guān)資料,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2020-09-09
詳解Java中ByteArray字節(jié)數(shù)組的輸入輸出流的用法
ByteArrayInputStream和ByteArrayOutputStream分別集成自InputStream和OutputStream這兩個(gè)輸入和輸出流,這里我們就來(lái)詳解Java中ByteArray字節(jié)數(shù)組的輸入輸出流的用法,需要的朋友可以參考下2016-06-06
SpringBoot獲取不到用戶(hù)真實(shí)IP的解決方法
最近遇到個(gè)問(wèn)題,項(xiàng)目部署后發(fā)現(xiàn)服務(wù)端無(wú)法獲取到客戶(hù)端真實(shí)的IP地址,本文就來(lái)介紹一下這個(gè)問(wèn)題的解決方法,感興趣的可以了解一下2023-08-08
Spring Data JPA 整合QueryDSL的使用案例
QueryDSL 是一個(gè)用于構(gòu)建類(lèi)型安全的 SQL 查詢(xún)的 Java 庫(kù),它的主要目標(biāo)是簡(jiǎn)化在 Java 中構(gòu)建和執(zhí)行 SQL 查詢(xún)的過(guò)程,同時(shí)提供類(lèi)型安全性和更好的編碼體驗(yàn),對(duì)Spring Data JPA 整合QueryDSL使用案例感興趣的朋友跟隨小編一起看看吧2023-08-08
劍指Offer之Java算法習(xí)題精講二叉樹(shù)與斐波那契函數(shù)
跟著思路走,之后從簡(jiǎn)單題入手,反復(fù)去看,做過(guò)之后可能會(huì)忘記,之后再做一次,記不住就反復(fù)做,反復(fù)尋求思路和規(guī)律,慢慢積累就會(huì)發(fā)現(xiàn)質(zhì)的變化2022-03-03

