色哟哟视频在线观看-色哟哟视频在线-色哟哟欧美15最新在线-色哟哟免费在线观看-国产l精品国产亚洲区在线观看-国产l精品国产亚洲区久久

0
  • 聊天消息
  • 系統(tǒng)消息
  • 評論與回復(fù)
登錄后你可以
  • 下載海量資料
  • 學(xué)習(xí)在線課程
  • 觀看技術(shù)視頻
  • 寫文章/發(fā)帖/加入社區(qū)
會員中心
創(chuàng)作中心

完善資料讓更多小伙伴認識你,還能領(lǐng)取20積分哦,立即完善>

3天內(nèi)不再提示

為什么需要Repository?什么才是好的Repository ?

jf_ro2CN3Fa ? 來源:geekhalo ? 2023-03-07 09:11 ? 次閱讀

1. 領(lǐng)域事件

領(lǐng)域事件是 DDD 中重要的模式之一,主要用于模型或系統(tǒng)間的解耦,提高系統(tǒng)的可擴展性和可維護性。

1.1. 什么是領(lǐng)域事件

領(lǐng)域事件是領(lǐng)域驅(qū)動設(shè)計(Domain-Driven Design,簡稱DDD)中的一個重要概念,特指在領(lǐng)域模型中發(fā)生的有意義的事件,是對領(lǐng)域模型中的重要業(yè)務(wù)動作執(zhí)行結(jié)果的抽象,如訂單創(chuàng)建、支付完成等。

在DDD中,領(lǐng)域事件是一種用于傳遞信息的機制,它使得不同領(lǐng)域模型之間的通信變得更加簡單和靈活。通過將事件分發(fā)給相關(guān)的訂閱者,可以讓不同的領(lǐng)域模型之間實現(xiàn)松耦合,從而更容易擴展和維護應(yīng)用程序。

領(lǐng)域事件通常由領(lǐng)域?qū)ο笾鲃佑|發(fā)并發(fā)布,而事件處理器則負責(zé)訂閱事件并對事件進行處理。通過事件發(fā)布和訂閱機制,可以在應(yīng)用程序中實現(xiàn)高效的事件驅(qū)動架構(gòu),從而更好地支持復(fù)雜的業(yè)務(wù)邏輯和業(yè)務(wù)流程。

說起來有點抽象,簡單舉個例子:假設(shè)有一個電子商務(wù)系統(tǒng),用戶下單后需要生成訂單并發(fā)送通知給相關(guān)人員。在領(lǐng)域模型中,可以定義一個 Order 領(lǐng)域?qū)ο?,該對象可以包含多個屬性,如訂單號、下單時間、購買的商品信息、收貨地址等等。當用戶下單時,可以通過調(diào)用 Order 對象的方法來生成訂單,同時也可以通過領(lǐng)域事件來發(fā)送通知。

具體來說,可以定義一個 OrderCreated 領(lǐng)域事件,用于表示訂單創(chuàng)建完成的事件,該事件包含一些必要的屬性,如訂單號、下單時間、購買的商品信息、收貨地址等等。當 Order 對象創(chuàng)建完成后,可以通過領(lǐng)域事件來觸發(fā)發(fā)送通知的操作,比如發(fā)送郵件或短信通知相關(guān)人員。

1.2. 領(lǐng)域事件的應(yīng)用場景

領(lǐng)域事件的應(yīng)用創(chuàng)建眾多,從圖中可以看出:

04b8ee02-bc7e-11ed-bfe3-dac502259ad0.png

領(lǐng)域事件可以:

保證聚合間的數(shù)據(jù)一致性。當一個聚合根上的操作引發(fā)了其他聚合根的變更時,將這些變更作為領(lǐng)域事件發(fā)布出去,其他聚合根可以訂閱這些事件并更新自己的狀態(tài),從而實現(xiàn)最終一致性。

替換批量處理。可以作為任務(wù)的觸發(fā)器,例如定時任務(wù)、異步任務(wù),避免定時+掃描這類批量處理。

實現(xiàn)事件源模式。將所有的領(lǐng)域事件全部存儲下來,可以用于恢復(fù)聚合的狀態(tài),實現(xiàn)事件源模式;也可以用于后續(xù)的審計和調(diào)試。

進行限界上下文集成。將事件從一個子域發(fā)布到另一個子域,使得這兩個子域可以解耦,不用相互知道彼此的存在。

領(lǐng)域事件雖好,但仍需技術(shù)框架進行支持,其實 Spring 的 Event 機制就足以滿足各類需求。

2. Spring 對 Event 的支持

在 Spring 中,事件的處理可以通過三種方式來實現(xiàn):

基于接口的事件處理:通過實現(xiàn) ApplicationListener 接口并重寫 onApplicationEvent 方法來處理事件。

基于注解的事件處理:通過在方法上添加 @EventListener 或 @TransactionEventListener 注解來處理事件,可以指定事件的類型以及監(jiān)聽的條件等。

基于異步事件處理:通過使用 @Async 注解來異步處理事件,可以提高應(yīng)用程序的響應(yīng)速度。

2.1. 基于接口的事件處理

由于與 Spring 存在強耦合,現(xiàn)在已經(jīng)很少使用,可以直接跳過。

下面是一個基于接口的事件處理的示例代碼:

@Component
publicclassMyEventListenerimplementsApplicationListener{
@Override
publicvoidonApplicationEvent(MyEventevent){
//處理事件
System.out.println("Receivedevent:"+event.getMessage());
}
}

publicclassMyEvent{
privateStringmessage;

publicMyEvent(Stringmessage){
this.message=message;
}

publicStringgetMessage(){
returnmessage;
}
}

@Component
publicclassMyEventPublisher{
@Autowired
privateApplicationEventPublishereventPublisher;

publicvoidpublishEvent(Stringmessage){
MyEventevent=newMyEvent(message);
eventPublisher.publishEvent(event);
}
}

在這個示例中,MyEvent 是一個自定義的事件類,MyEventListener 是一個實現(xiàn)了 ApplicationListener 接口的監(jiān)聽器,用于處理 MyEvent 事件,MyEventPublisher 是用于發(fā)布事件的類。

當應(yīng)用程序調(diào)用 MyEventPublisher 的 publishEvent 方法時,會觸發(fā)一個 MyEvent 事件,MyEventListener 中的 onApplicationEvent 方法將被自動調(diào)用,從而處理這個事件。

2.2. 基于注解的事件處理

Spring 提供 @EventListener 和 @TransactionListener 兩個注解以簡化對事件的處理。

2.2.1. @EventListener

Spring 的 EventListener 監(jiān)聽器是一種相對于傳統(tǒng)的事件監(jiān)聽方式更為簡潔和靈活的事件機制。與傳統(tǒng)的事件機制不同,EventListener 不需要顯示地繼承特定的事件接口,而是使用注解標識需要監(jiān)聽的事件類型,然后通過一個單獨的監(jiān)聽器類處理所有類型的事件。

相比之下 EventListener 的優(yōu)勢主要有以下幾點:

更加靈活:EventListener 不依賴于任何特定的事件接口,從而使得事件處理更加靈活,可以監(jiān)聽和處理任意類型的事件。

更加簡潔:相比傳統(tǒng)的事件監(jiān)聽方式,使用 EventListener 可以避免一系列繁瑣的接口定義和實現(xiàn),簡化了代碼結(jié)構(gòu),使得開發(fā)效率更高。

更加松耦合:EventListener 將事件發(fā)布方和事件處理方分離,遵循松耦合的設(shè)計原則,提高了代碼的可維護性和擴展性。

更加可測試:由于 EventListener 可以監(jiān)聽和處理任意類型的事件,可以通過單元測試驗證其功能是否正確,從而提高了測試的可靠性。

以下是一個簡單的例子:

@Component
publicclassMyEventListener{

@EventListener
publicvoidonApplicationEvent(MyEventevent){
//處理事件
System.out.println("Receivedevent:"+event.getMessage());
}
}

publicclassMyEvent{
privateStringmessage;

publicMyEvent(Stringmessage){
this.message=message;
}

publicStringgetMessage(){
returnmessage;
}
}

@Component
publicclassMyEventPublisher{

@Autowired
privateApplicationEventPublishereventPublisher;

publicvoidpublishEvent(Stringmessage){
MyEventevent=newMyEvent(message);
eventPublisher.publishEvent(event);
}
}

相比基于接口的事件處理,EventListener 是一種更加簡潔、靈活、松耦合、可測試的事件機制,能夠有效地降低開發(fā)的復(fù)雜度,提高開發(fā)效率。

2.2.2. @TransactionEventListener

在 Spring 中,TransactionEventListner 和 EventListner 都是用于處理事件的接口。不同之處在于

TransactionEventListner 是在事務(wù)提交后才會觸發(fā)

而 EventListner 則是在事件發(fā)布后就會觸發(fā)。

具體來說,在使用 Spring 的聲明式事務(wù)時,可以在事務(wù)提交后觸發(fā)某些事件。這就是 TransactionEventListner 的應(yīng)用場景。而 EventListner 則不涉及事務(wù),可以用于在事件發(fā)布后觸發(fā)一些操作。

下面是一個簡單的示例,演示了如何使用 TransactionEventListner 和 EventListner:

@Component
publicclassMyEventListener{

@EventListener
publicvoidhandleMyEvent(MyEventevent){
//處理MyEvent
}

@TransactionalEventListener
publicvoidhandleMyTransactionalEvent(MyTransactionalEventevent){
//處理MyTransactionalEvent
}
}

@Service
publicclassMyService{

@Autowired
privateApplicationEventPublishereventPublisher;

@Autowired
privateMyRepositorymyRepository;

@Transactional
publicvoiddoSomething(){
//做一些事情
MyEntityentity=myRepository.findById(1L);
//發(fā)布事件
eventPublisher.publishEvent(newMyEvent(this,entity));
//發(fā)布事務(wù)事件
eventPublisher.publishEvent(newMyTransactionalEvent(this,entity));
}
}

在這個例子中,MyEventListener 類定義了兩個方法,handleMyEvent 和 handleMyTransactionalEvent,分別處理 MyEvent 和 MyTransactionalEvent 事件。其中,handleMyTransactionalEvent 方法用 @TransactionalEventListener 注解標記,表示它只會在事務(wù)提交后觸發(fā)。

MyService 類中的 doSomething 方法使用 ApplicationEventPublisher 來發(fā)布事件。注意,它發(fā)布了兩種不同類型的事件:MyEvent 和 MyTransactionalEvent。這兩個事件會分別觸發(fā) MyEventListener 中的對應(yīng)方法。

總的來說,Spring 的事件機制非常靈活,可以方便地擴展應(yīng)用程序的功能。TransactionEventListner 和 EventListner 這兩個接口的應(yīng)用場景有所不同,可以根據(jù)實際需求選擇使用。

2.3.基于異步事件處理

@Async是Spring框架中的一個注解,用于將一個方法標記為異步執(zhí)行。使用該注解,Spring將自動為該方法創(chuàng)建一個新線程,使其在后臺異步執(zhí)行,不會阻塞主線程的執(zhí)行。

在具體應(yīng)用中,使用@Async可以大大提升應(yīng)用的并發(fā)處理能力,使得系統(tǒng)能夠更快地響應(yīng)用戶請求,提高系統(tǒng)的吞吐量。

@Async 和 @EventListener 或 @TransactionEventListener 注解在一起使用時,會產(chǎn)生異步的事件處理器。使用這種組合的方式,事件處理器會在單獨的線程池中執(zhí)行,以避免阻塞主線程。這種方式在需要處理大量事件或者事件處理器耗時較長的情況下非常有用,可以有效提高應(yīng)用的性能和可伸縮性。同時,Spring 框架對這種方式也提供了完善的支持,可以方便地使用這種方式來實現(xiàn)異步事件處理。

下面是一個簡單的示例代碼,演示了如何在 Spring 中使用 @Async 和 @EventListener 一起實現(xiàn)異步事件處理:

@Component
publicclassExampleEventListener{

@Async
@EventListener
publicvoidhandleExampleEvent(ExampleEventevent){
//在新的線程中執(zhí)行異步邏輯
//...
}
}

在這個示例中,ExampleEventListener 類中的 handleExampleEvent 方法使用了 @Async 和 @EventListener 注解,表示這個方法是一個異步事件監(jiān)聽器。當一個 ExampleEvent 事件被觸發(fā)時,這個方法會被異步地執(zhí)行。在這個方法中,可以執(zhí)行任何異步的邏輯處理,比如向隊列發(fā)送消息、調(diào)用其他服務(wù)等。

備注:在使用 @Async 時,需要根據(jù)業(yè)務(wù)場景對線程池進行自定義,以免出現(xiàn)資源不夠的情況(Spring 默認使用單線程處理@Async異步任務(wù))

4. 場景分析

綜上所述,當領(lǐng)域事件發(fā)出來之后,不同的注解會產(chǎn)生不同的行為,簡單匯總?cè)缦拢?/p>

@EventListener @TransactionEventListener
無 @Async 順序、同步執(zhí)行 事務(wù)提交后、同步執(zhí)行
有 @Async 順序、異步執(zhí)行 事務(wù)提交后、異步執(zhí)行

4.1. @EventListener

04e6afea-bc7e-11ed-bfe3-dac502259ad0.png

特點:

順序執(zhí)行。調(diào)用 publish(Event) 后,自動觸發(fā)對 @EventListner 注釋方法的調(diào)用

同步執(zhí)行。使用主線程執(zhí)行,方法拋出異常會中斷調(diào)用鏈路,會觸發(fā)事務(wù)的回歸

應(yīng)用場景:

事務(wù)消息表。在同一事務(wù)中完成對業(yè)務(wù)數(shù)據(jù)和消息表的修改

業(yè)務(wù)驗證。對業(yè)務(wù)對象進行最后一次驗證,如果驗證不通過直接拋出異常中斷數(shù)據(jù)庫事務(wù)

業(yè)務(wù)插件。在當前線程和事務(wù)中執(zhí)行插件完成業(yè)務(wù)擴展

4.2. @TransactionEventListener

04f892e6-bc7e-11ed-bfe3-dac502259ad0.png

特點:

事務(wù)提交后執(zhí)行。調(diào)用 publish(Event) 時,只是向上下文中注冊了一個回調(diào)器,并不會立即執(zhí)行;只有在事務(wù)提交后,才會觸發(fā)對 @TransactionEventListner 注釋方法的調(diào)用

同步執(zhí)行。使用主線程執(zhí)行,方法拋出異常會中斷調(diào)用鏈路,當不會回歸事務(wù)(事務(wù)已提交,沒有辦法進行回歸)

應(yīng)用場景:

數(shù)據(jù)同步。事務(wù)提交后,將變更同步到 ES 或 Cache

記錄審計日志。只有在業(yè)務(wù)變更成功更新到數(shù)據(jù)庫時才進行記錄

備注:@TransactionEventLisnter 必須在事務(wù)上下文中,脫離上下文,調(diào)用不會生效

4.3. @EventListener + @Async

0509c2b4-bc7e-11ed-bfe3-dac502259ad0.png

特點:

順序執(zhí)行。調(diào)用 publish(Event) 后,自動觸發(fā)對 @EventListner 注釋方法的調(diào)用

異步執(zhí)行。使用獨立的線程池執(zhí)行任務(wù),方法拋出異常對主流程沒有任何影響

應(yīng)用場景:

記日志明細日志,輔助排查問題

4.4. @TransactionEventListener + @Async

051f67cc-bc7e-11ed-bfe3-dac502259ad0.png

特點:

事務(wù)提交后執(zhí)行。調(diào)用 publish(Event) 時,只是向上下文中注冊了一個回調(diào)器,并不會立即執(zhí)行;只有在事務(wù)提交后,才會觸發(fā)對 @TransactionEventListner 注釋方法的調(diào)用

異步執(zhí)行。使用獨立的線程池執(zhí)行任務(wù),方法拋出異常對主流程沒有任何影響

應(yīng)用場景:異步處理。記錄操作日志,異步保存數(shù)據(jù)等 備注:@TransactionEventLisnter 必須在事務(wù)上下文中,脫離上下文,調(diào)用不會生效

5. 小結(jié)

領(lǐng)域事件的落地,不僅需要強大的設(shè)計能力,還需要與之匹配的基礎(chǔ)設(shè)施。Spring 作為最常用的框架,基于發(fā)布訂閱實現(xiàn)了完整的一套 Event 管理機制。工具在手是否能根據(jù)業(yè)務(wù)場景選擇合適的解決方案就成了研發(fā)的職責(zé),簡單思考以下組合適用場景是什么:

@EventListener

@TransactionEventListener

@EventListener + @Async

@TransactionEventListener + @Async






審核編輯:劉清

聲明:本文內(nèi)容及配圖由入駐作者撰寫或者入駐合作網(wǎng)站授權(quán)轉(zhuǎn)載。文章觀點僅代表作者本人,不代表電子發(fā)燒友網(wǎng)立場。文章及其配圖僅供工程師學(xué)習(xí)之用,如有內(nèi)容侵權(quán)或者其他違規(guī)問題,請聯(lián)系本站處理。 舉報投訴
  • JAVA
    +關(guān)注

    關(guān)注

    19

    文章

    2970

    瀏覽量

    104812
  • MySQL
    +關(guān)注

    關(guān)注

    1

    文章

    816

    瀏覽量

    26607
  • MYSQL數(shù)據(jù)庫
    +關(guān)注

    關(guān)注

    0

    文章

    96

    瀏覽量

    9395
  • ddd
    ddd
    +關(guān)注

    關(guān)注

    0

    文章

    23

    瀏覽量

    2932

原文標題:Spring Event + DDD = 王炸!!

文章出處:【微信號:芋道源碼,微信公眾號:芋道源碼】歡迎添加關(guān)注!文章轉(zhuǎn)載請注明出處。

收藏 人收藏

    評論

    相關(guān)推薦

    modusToolbox在加載離線庫時,總是在loading device_db時提示錯誤的原因?

    /https___github.com_Infineon_device-db/device-db\' does not appear to be a git repository fatal: Could not read from
    發(fā)表于 02-02 08:07

    使用MotorControl Workbench生成代碼時出錯的原因?

    各位大師你們!使用MotorControl Workbench生成代碼時出錯,請高手指教,謝謝。 Code generation started CMSIS Pack version
    發(fā)表于 04-18 07:08

    How to download and install AD10 when using proxy servers

    create your own installation repository. This provides a local install solution for computers
    發(fā)表于 09-05 10:54

    MATLAB請教各位大神

    ModelAdvisor.Repository/connect (line 14)出錯 ModelAdvisor.Repository (line 14)出錯 Simulink.ModelAdvisor/getWorkDir
    發(fā)表于 10-24 18:42

    插牌具有什么功能才是需要的?

    插牌具有什么功能才是需要的?
    發(fā)表于 07-13 13:57

    ESP-IDF使用:請問怎么樣能測試esp32的spp example

    各位大佬指點迷津。$ makefatal: Not a git repository (or any of the parent directories): .gitfatal: Not a git
    發(fā)表于 08-17 09:22

    STM32CubeMX芯片包(固件庫)使用注意事項

    1. 解壓本地固件庫包后需要將文件夾放到指定路徑,該指定路徑為cubemx軟件中的help -> updater settings -> updater settings ->
    發(fā)表于 07-23 09:03

    STM32CubeIDE不顯示“Inizialize all peripherals with their Default Mode”怎么解決?

    大家,我有這個痛苦的問題:當我想創(chuàng)建一個新項目時,選擇板子和項目名稱后點擊“完成”并沒有顯示可以選擇加載外設(shè)默認模式的窗口,而是立即加載空白配置。我試過其他版本的多維數(shù)據(jù)集并刪除“\Repository”但沒有任何改變。請問有什么建議嗎?
    發(fā)表于 01-03 09:50

    STM32CubeMX系列6版本刪除主文件夾中存在的所有文件夾,從而刪除用戶創(chuàng)建的文件夾要如何避免?

    我將 STM32CubeMX 安裝到文件夾C:\STM32CubeMX,然后將 REPOSITORY FOLDER 設(shè)置為C:\STM32CubeMX\Repository,因為我想將
    發(fā)表于 01-13 08:32

    如何在Touchgfx設(shè)計器中開始使用來自touchgfx-open-repository的圖形小部件?

    代碼讓它們做一些事情。我看不到添加圖表的方法,所以我用谷歌搜索了一下,發(fā)現(xiàn)您需要來自此處存儲庫的圖表小部件:https ://github.com/touchgfx
    發(fā)表于 01-30 08:09

    如何在代碼中從touchgfx-open-repository添加二維碼小部件?

    ) 、 qrCode.setQRCode(&code) 、 qrCode.setScale(4) 、 add(qrCode) 方法,但我找不到它。https://github.com/touchgfx/touchgfx-open-repository/tree/master/widgets/QRCode你能幫忙嗎?
    發(fā)表于 02-08 07:44

    【米爾MYD-JX8MMA7開發(fā)板-ARM+FPGA架構(gòu)試用體驗】快速入門

    : The repository 'http://ftp.debian.org/debian buster InRelease' is not signed.N: Updating from such a
    發(fā)表于 03-09 19:04

    mirror和repository的區(qū)別分析

    internal repository是指在局域網(wǎng)內(nèi)部搭建的repository,它跟central repository, jboss repository等的區(qū)別僅僅在于其URL是
    發(fā)表于 11-29 10:42 ?4243次閱讀
    mirror和<b class='flag-5'>repository</b>的區(qū)別分析

    怎么樣才是一臺電腦

    怎么樣才是一臺電腦?即使是天天進行測試的的編輯,都要不斷地面對和解決這個問題。性能,穩(wěn)定性,兼容性,平臺能力,都對都很重要,而單獨強調(diào)某一個側(cè)面卻都不夠全面。
    發(fā)表于 05-17 14:46 ?1695次閱讀

    pip安裝更換鏡像

    使用pip來安裝python包有時候安裝起來會非常慢,因此需要換成國內(nèi)的源來加速下載: 使用命令 以Torch為例: pip install -i https
    的頭像 發(fā)表于 01-11 14:54 ?620次閱讀
    主站蜘蛛池模板: 无码AV熟妇素人内射V在线| 在线成人精品国产区免费| 无限资源日本2019版免费| 一本色道久久综合亚洲精品加 | 午夜伦伦电影理论片大片| 在线观看永久免费网站| 调教椅上的调教SM总裁被调教| 九九久久久| 三级全黄的视频| 樱花动漫成人隐藏入口| 工口肉肉彩色不遮挡| 快播苍井空| 牲高潮99爽久久久久777| 亚洲日本香蕉视频观看视频| bbbbbxxxxx肥胖| 色婷婷亚洲精品天天综合影院| 国产免费怕怕免费视频观看| 亚洲色欲国产AV精品综合| 欧美精品AV无码一区二区| 国产成人自拍视频在线观看| 免费看黄色小说| 亚洲国产精品嫩草影院| 99亚偷拍自图区亚洲| 好男人在线视频| 色窝窝亚洲AV在线观看| 999www成人免费视频| 久久国产精品麻豆AV影视| 四房播播开心五月| www.久久精品视频| 蜜桃传媒在线播放| 亚洲视频在线观| 国产一区二区在线免费观看| 日日夜夜撸 在线影院| 97色伦久久视频在观看| 精品视频网站| 亚洲国产精品无码AV久久久| 父亲在线日本综艺免费观看全集 | 99久久全国免费久久爱| 久久re热在线视频精99| 性饥渴姓交HDSEX| 国产精品美女WWW爽爽爽视频|