最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

Java自定義事件監(jiān)聽(tīng)器的實(shí)現(xiàn)方式和應(yīng)用場(chǎng)景

 更新時(shí)間:2025年10月17日 10:02:38   作者:IT橘子皮  
自定義事件監(jiān)聽(tīng)器是一種強(qiáng)大的編程模式,它主要實(shí)現(xiàn)了模塊間的解耦、增強(qiáng)了應(yīng)用的擴(kuò)展性和可維護(hù)性,本文小編給大家介紹了Java自定義事件監(jiān)聽(tīng)器的實(shí)現(xiàn)方式和應(yīng)用場(chǎng)景,需要的朋友可以參考下

引言

自定義事件監(jiān)聽(tīng)器是一種強(qiáng)大的編程模式,它主要實(shí)現(xiàn)了模塊間的解耦增強(qiáng)了應(yīng)用的擴(kuò)展性可維護(hù)性。其核心思想是 ??“觀察者模式”??:一個(gè)對(duì)象(事件發(fā)布者)執(zhí)行特定操作時(shí),無(wú)需直接調(diào)用其他對(duì)象的方法,而是通過(guò)發(fā)布一個(gè)事件,由對(duì)該事件感興趣的其他對(duì)象(事件監(jiān)聽(tīng)器)來(lái)執(zhí)行相應(yīng)的操作。

下面這個(gè)表格能幫你快速了解其核心價(jià)值。

核心價(jià)值說(shuō)明
?模塊化解耦?事件發(fā)布者無(wú)需知道也不直接調(diào)用具體的業(yè)務(wù)處理器,兩者通過(guò)事件中介,依賴關(guān)系變得松散。
?增強(qiáng)擴(kuò)展性?需要新增一種處理邏輯時(shí),只需增加一個(gè)新的監(jiān)聽(tīng)器即可,無(wú)需修改原有發(fā)布者和其他監(jiān)聽(tīng)器的代碼。
?實(shí)現(xiàn)異步處理?監(jiān)聽(tīng)器可以配置為異步執(zhí)行,讓主流程(如處理用戶請(qǐng)求)能快速返回,提升響應(yīng)速度。
?增強(qiáng)可觀察性?關(guān)鍵業(yè)務(wù)節(jié)點(diǎn)的狀態(tài)變化(如訂單狀態(tài)變更、用戶行為)都可以通過(guò)事件被記錄和追蹤。
?統(tǒng)一處理邏輯?可以將一些通用的橫切關(guān)注點(diǎn)(如日志記錄、性能監(jiān)控)集中到事件監(jiān)聽(tīng)器中處理。

具體應(yīng)用場(chǎng)景示例

1. 用戶注冊(cè)后的后續(xù)操作

這是一個(gè)非常經(jīng)典的應(yīng)用場(chǎng)景。用戶注冊(cè)核心邏輯(保存用戶信息)完成后,往往需要執(zhí)行一系列后續(xù)操作。

?傳統(tǒng)緊耦合方式的缺點(diǎn)?:在 UserServiceregister方法里,你可能會(huì)直接調(diào)用 EmailService.sendWelcomeEmail(), PointsService.addSignupPoints(), SmsService.sendVerificationCode()等方法。這導(dǎo)致注冊(cè)服務(wù)依賴了眾多不相關(guān)的服務(wù),任何后續(xù)操作的增減都需要修改注冊(cè)服務(wù)的代碼,違反了“開(kāi)閉原則”。

?使用事件監(jiān)聽(tīng)器解耦?:

?事件 (Event)??:定義 UserRegisteredEvent,包含注冊(cè)用戶的基本信息。

?發(fā)布者 (Publisher)??:在 UserService成功保存用戶后,發(fā)布 UserRegisteredEvent事件。

?監(jiān)聽(tīng)器 (Listeners)??:

  • EmailSenderListener:監(jiān)聽(tīng)事件,發(fā)送歡迎郵件。
  • PointsGrantListener:監(jiān)聽(tīng)事件,為新用戶增加積分。
  • AnalyticsListener:監(jiān)聽(tīng)事件,向數(shù)據(jù)分析平臺(tái)發(fā)送用戶注冊(cè)消息。
// 示例代碼基于Spring框架
// 1. 定義事件
public class UserRegisteredEvent extends ApplicationEvent {
    private User user;
    public UserRegisteredEvent(Object source, User user) {
        super(source);
        this.user = user;
    }
    // getter ...
}

// 2. 在服務(wù)中發(fā)布事件
@Service
public class UserService {
    @Autowired
    private ApplicationEventPublisher publisher;

    public void register(User user) {
        // ... 保存用戶等核心邏輯
        // 發(fā)布事件
        publisher.publishEvent(new UserRegisteredEvent(this, user));
    }
}

// 3. 實(shí)現(xiàn)多個(gè)監(jiān)聽(tīng)器
@Component
public class EmailSenderListener {
    @EventListener
    public void handleUserRegistered(UserRegisteredEvent event) {
        // 發(fā)送歡迎郵件的邏輯
    }
}

@Component
public class PointsGrantListener {
    @EventListener
    @Async // 表明異步執(zhí)行,不阻塞主線程
    public void handleUserRegistered(UserRegisteredEvent event) {
        // 增加積分的邏輯
    }
}

這樣一來(lái),UserService只負(fù)責(zé)核心業(yè)務(wù)和發(fā)布事件,變得非常純粹。新增或取消任何注冊(cè)后操作,都不會(huì)影響到它。

2. 微服務(wù)間的數(shù)據(jù)同步

在微服務(wù)架構(gòu)中,服務(wù)A完成某個(gè)操作后,可能需要通知服務(wù)B更新其數(shù)據(jù)。

?場(chǎng)景?:訂單服務(wù)創(chuàng)建訂單后,需要通知用戶服務(wù)更新用戶的最近訂單信息。

?實(shí)現(xiàn)?:

  • 訂單服務(wù)在處理完創(chuàng)建訂單的邏輯后,發(fā)布一個(gè) OrderCreatedEvent事件。
  • 一個(gè)專門的數(shù)據(jù)同步監(jiān)聽(tīng)器會(huì)捕獲到這個(gè)事件,然后通過(guò)HTTP請(qǐng)求、消息隊(duì)列等方式,將訂單數(shù)據(jù)同步給用戶服務(wù)。

?優(yōu)勢(shì)?:訂單服務(wù)完全不需要關(guān)心用戶服務(wù)的存在和具體實(shí)現(xiàn),實(shí)現(xiàn)了服務(wù)之間的解耦。

3. 系統(tǒng)啟動(dòng)時(shí)的資源初始化

監(jiān)聽(tīng)系統(tǒng)生命周期事件,完成一些初始化工作。

?場(chǎng)景?:應(yīng)用啟動(dòng)后,將一些不常變但頻繁訪問(wèn)的數(shù)據(jù)(如城市列表、配置項(xiàng))從數(shù)據(jù)庫(kù)加載到緩存。

?實(shí)現(xiàn)?:

  • 創(chuàng)建一個(gè)監(jiān)聽(tīng)器,監(jiān)聽(tīng)Spring的 ContextRefreshedEvent(應(yīng)用上下文刷新完成事件)。
  • 在該監(jiān)聽(tīng)器的處理函數(shù)中,執(zhí)行加載數(shù)據(jù)到緩存的操作。
@Component
public class CacheWarmUpListener implements ApplicationListener<ContextRefreshedEvent> {
    @Override
    public void onApplicationEvent(ContextRefreshedEvent event) {
        // 將常用數(shù)據(jù)加載到緩存(如Redis)
    }
}

實(shí)現(xiàn)事件監(jiān)聽(tīng)器的方式

在Spring框架中,主要有兩種方式:

  1. ?實(shí)現(xiàn) ApplicationListener接口?:這是一個(gè)傳統(tǒng)的、面向類的方式。
  2. ?使用 @EventListener注解?:這是一個(gè)更現(xiàn)代、靈活的方式,可以標(biāo)注在任何Bean的方法上,方法簽名就是事件類型。這是目前最推薦和使用最廣泛的方式。

實(shí)踐注意事項(xiàng)

  1. ?確保監(jiān)聽(tīng)器是無(wú)狀態(tài)的?:監(jiān)聽(tīng)器通常被設(shè)計(jì)為單例,要避免在其中保存會(huì)變化的狀態(tài),以免引發(fā)并發(fā)問(wèn)題。
  2. ?處理好異常?:監(jiān)聽(tīng)器中的異常如果未捕獲,可能會(huì)中斷事件傳播鏈,影響其他監(jiān)聽(tīng)器,甚至可能回滾發(fā)布者的事務(wù)(如果事務(wù)邊界包含事件發(fā)布)。需要根據(jù)業(yè)務(wù)重要性決定是記錄日志、重試還是拋出異常。
  3. ?謹(jǐn)慎使用異步?:為監(jiān)聽(tīng)器添加 @Async實(shí)現(xiàn)異步處理能提升響應(yīng)速度,但要考慮:如果應(yīng)用重啟,異步執(zhí)行的任務(wù)可能會(huì)丟失;同時(shí),異步環(huán)境下的事務(wù)邊界需要仔細(xì)處理。
  4. ?避免內(nèi)存泄漏?:在Web前端(如使用JavaScript自定義事件),當(dāng)DOM元素被移除時(shí),要記得使用 removeEventListener移除監(jiān)聽(tīng)器,防止內(nèi)存泄漏。

希望這些解釋和例子能幫助你深刻理解自定義事件監(jiān)聽(tīng)器的意義和威力!

以上就是Java自定義事件監(jiān)聽(tīng)器的實(shí)現(xiàn)方式和應(yīng)用場(chǎng)景的詳細(xì)內(nèi)容,更多關(guān)于Java自定義事件監(jiān)聽(tīng)器的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

  • Java類之間的關(guān)系圖_動(dòng)力節(jié)點(diǎn)Java學(xué)院整理

    Java類之間的關(guān)系圖_動(dòng)力節(jié)點(diǎn)Java學(xué)院整理

    在Java以及其他的面向?qū)ο笤O(shè)計(jì)模式中,類與類之間主要有6種關(guān)系,他們分別是:依賴、關(guān)聯(lián)、聚合、組合、繼承、實(shí)現(xiàn)。他們的耦合度依次增強(qiáng),有興趣的可以了解一下
    2017-08-08
  • 詳解Java中wait和sleep的區(qū)別

    詳解Java中wait和sleep的區(qū)別

    這篇文章主要介紹了Java中wait和sleep的區(qū)別,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2019-03-03
  • SpringBoot 中大文件(分片上傳)斷點(diǎn)續(xù)傳與極速秒傳功能的實(shí)現(xiàn)

    SpringBoot 中大文件(分片上傳)斷點(diǎn)續(xù)傳與極速秒傳功能的實(shí)現(xiàn)

    這篇文章主要介紹了SpringBoot 中大文件(分片上傳)斷點(diǎn)續(xù)傳與極速秒傳功能的實(shí)現(xiàn),本文通過(guò)實(shí)例代碼給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2020-07-07
  • 簡(jiǎn)單了解java獲取類的3種方式

    簡(jiǎn)單了解java獲取類的3種方式

    這篇文章主要介紹了java獲取類的3種方式詳解,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下
    2019-10-10
  • 如何解決java.lang.IllegalStateException: Target host is null的問(wèn)題

    如何解決java.lang.IllegalStateException: Target host&n

    文章描述了通過(guò)MocoRunner模擬接口,并使用properties文件和ResourceBundle讀取配置文件進(jìn)行g(shù)et請(qǐng)求的過(guò)程,在執(zhí)行過(guò)程中遇到了目標(biāo)主機(jī)為空的錯(cuò)誤,通過(guò)檢查和修正url拼接問(wèn)題解決了該錯(cuò)誤
    2024-12-12
  • 詳解Mybatis中的select方法

    詳解Mybatis中的select方法

    這篇文章主要介紹了Mybatis的select方法,通過(guò)代碼給大家詳細(xì)介紹了selectByExample方法,selectById方法,需要的朋友可以參考下
    2018-07-07
  • java8、jdk8日期轉(zhuǎn)化成字符串詳解

    java8、jdk8日期轉(zhuǎn)化成字符串詳解

    在本篇文章中小編給大家整理了關(guān)于java8、jdk8日期轉(zhuǎn)化成字符串的相關(guān)知識(shí)點(diǎn)和代碼,需要的朋友們學(xué)習(xí)下。
    2019-04-04
  • Java實(shí)現(xiàn)將TXT文本文件轉(zhuǎn)換為PDF文件

    Java實(shí)現(xiàn)將TXT文本文件轉(zhuǎn)換為PDF文件

    與TXT文本文件,PDF文件更加專業(yè)也更適合傳輸,所以這篇文章小編主要為大家詳細(xì)介紹了如何使用Java實(shí)現(xiàn)將TXT文本文件轉(zhuǎn)換為PDF文件 ,需要的可以參考下
    2024-02-02
  • Java+MySQL實(shí)現(xiàn)學(xué)生信息管理系統(tǒng)源碼

    Java+MySQL實(shí)現(xiàn)學(xué)生信息管理系統(tǒng)源碼

    這篇文章主要為大家詳細(xì)介紹了Java+MySQL實(shí)現(xiàn)學(xué)生信息管理系統(tǒng),文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2017-11-11
  • 深入講解Java的對(duì)象頭與對(duì)象組成

    深入講解Java的對(duì)象頭與對(duì)象組成

    由于Java面向?qū)ο蟮乃枷?在JVM中需要大量存儲(chǔ)對(duì)象,存儲(chǔ)時(shí)為了實(shí)現(xiàn)一些額外的功能,需要在對(duì)象中添加一些標(biāo)記字段用于增強(qiáng)對(duì)象功能,這些標(biāo)記字段組成了對(duì)象頭,下面這篇文章主要給大家介紹了關(guān)于Java對(duì)象頭與對(duì)象組成的相關(guān)資料,需要的朋友可以參考下
    2022-02-02

最新評(píng)論

磐安县| 拉孜县| 沛县| 北安市| 罗甸县| 霍林郭勒市| 襄垣县| 黄陵县| 通州区| 金平| 阜新| 淮南市| 磴口县| 祁阳县| 丰都县| 定州市| 满城县| 电白县| 莱州市| 长汀县| 宽甸| 黑山县| 蚌埠市| 青浦区| 罗甸县| 嘉禾县| 台湾省| 宣城市| 乌拉特中旗| 区。| 铜梁县| 榕江县| 武威市| 隆回县| 渭源县| 临泽县| 文化| 通城县| 普安县| 怀集县| 安塞县|