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

SpringBoot實現(xiàn)異步事件驅(qū)動的方法

 更新時間:2021年06月28日 11:35:12   作者:飄渺Jam  
本文主要介紹了SpringBoot實現(xiàn)異步事件驅(qū)動的方法,文中通過示例代碼介紹的非常詳細,對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧

在項目實際開發(fā)過程中,我們有很多這樣的業(yè)務(wù)場景:一個事務(wù)中處理完一個業(yè)務(wù)邏輯后需要跟著處理另外一個業(yè)務(wù)邏輯,偽碼大致如下:

@Service
public class ProductServiceImpl {
 ...
    public void saveProduct(Product product) {
        productMapper.saveOrder(product);
        notifyService.notify(product);
    }
 ...
}

很簡單并且很常見的一段業(yè)務(wù)邏輯:首先將產(chǎn)品先保存數(shù)據(jù)庫,然后發(fā)送通知。

某一天你們可能需要把新增的產(chǎn)品存到Es中,這時候也需要代碼可能變成這樣:

@Service
public class ProductServiceImpl {
 ...
    public void saveProduct(Product product) {
        productMapper.saveProduct(product);
        esService.saveProduct(product)
        notifyService.notify(product);
    }
 ...
}

隨著業(yè)務(wù)需求的變化,代碼也需要跟著一遍遍的修改。而且還會存在另外一個問題,如果通知系統(tǒng)掛了,那就不能再新增產(chǎn)品了。

對于上面這種情況非常適合引入消息中間件(消息隊列)來對業(yè)務(wù)進行解耦,但并非所有的業(yè)務(wù)系統(tǒng)都會引入消息中間件(引入會第三方架構(gòu)組件會帶來很大的運維成本)。

Spring提供了事件驅(qū)動機制可以幫助我們實現(xiàn)這一需求。

Spring事件驅(qū)動

spring事件驅(qū)動由3個部分組成

  • ApplicationEvent:表示事件本身,自定義事件需要繼承該類,用來定義事件
  • ApplicationEventPublisher:事件發(fā)送器,主要用來發(fā)布事件
  • ApplicationListener:事件監(jiān)聽器接口,監(jiān)聽類實現(xiàn)ApplicationListener 里onApplicationEvent方法即可,也可以在方法上增加@EventListener以實現(xiàn)事件監(jiān)聽。

實現(xiàn)Spring事件驅(qū)動一般只需要三步:

  • 自定義需要發(fā)布的事件類,需要繼承ApplicationEvent類
  • 使用ApplicationEventPublisher來發(fā)布自定義事件
  • 使用@EventListener來監(jiān)聽事件

這里需要特別注意一點,默認情況下事件是同步的。即事件被publish后會等待Listener的處理。如果發(fā)布事件處的業(yè)務(wù)存在事務(wù),監(jiān)聽器處理也會在相同的事務(wù)中。如果需要異步處理事件,可以onApplicationEvent方法上加@Aync支持異步或在有@EventListener的注解方法上加上@Aync。

源碼實戰(zhàn)

創(chuàng)建事件

public class ProductEvent extends ApplicationEvent {
    public ProductEvent(Product product) {
        super(product);
    }
}

發(fā)布事件

@Service
public class ProductServiceImpl implements IproductService {
 ...
    @Autowired
    private ApplicationEventPublisher publisher;
 
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void saveProduct(Product product) {
  productMapper.saveProduct(product); 
        //事件發(fā)布
        publisher.publishEvent(product);
    }
    ...
}

事件監(jiān)聽

@Slf4j
@AllArgsConstructor
public class ProductListener {

 private final NotifyService notifyServcie;

 @Async
 @Order
 @EventListener(ProductEvent.class)
 public void notify(ProductEvent event) {
  Product product = (Product) event.getSource();
  notifyServcie.notify(product, "product");
 }
}

在SpringBoot啟動類上增加@EnableAsync 注解

@Slf4j
@EnableSwagger2
@SpringBootApplication
@EnableAsync
public class ApplicationBootstrap {
...
}

使用了Async后會使用默認的線程池SimpleAsyncTaskExecutor,一般我們會在項目中自定義一個線程池。

@Configuration
public class ExecutorConfig {
    /** 核心線程數(shù) */
    private int corePoolSize = 10;
    /** 最大線程數(shù)  */
    private int maxPoolSize = 50;
    /** 隊列大小  */
    private int queueCapacity = 10;
    /** 線程最大空閑時間   */
    private int keepAliveSeconds = 150;

    @Bean("customExecutor")
    public Executor myExecutor() {
        ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
        executor.setCorePoolSize(corePoolSize);
        executor.setMaxPoolSize(maxPoolSize);
        executor.setQueueCapacity(queueCapacity);
        executor.setThreadNamePrefix("customExecutor-");
        executor.setKeepAliveSeconds(keepAliveSeconds);

        // rejection-policy:當(dāng)pool已經(jīng)達到max size的時候,如何處理新任務(wù)
        // CALLER_RUNS:不在新線程中執(zhí)行任務(wù),而是由調(diào)用者所在的線程來執(zhí)行
        executor.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy());
        executor.initialize();
        return executor;
    }
}

到此這篇關(guān)于SpringBoot實現(xiàn)異步事件驅(qū)動的方法的文章就介紹到這了,更多相關(guān)SpringBoot 異步事件驅(qū)動內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • Java編程中的條件判斷之if語句的用法詳解

    Java編程中的條件判斷之if語句的用法詳解

    這篇文章主要介紹了Java編程中的條件判斷之if語句的用法詳解,是Java入門學(xué)習(xí)中的基礎(chǔ)知識,需要的朋友可以參考下
    2015-11-11
  • kafka添加安全驗證配置方式

    kafka添加安全驗證配置方式

    這篇文章主要介紹了kafka添加安全驗證配置方式,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2022-10-10
  • SpringBoot實現(xiàn)數(shù)據(jù)源動態(tài)切換的最佳姿勢

    SpringBoot實現(xiàn)數(shù)據(jù)源動態(tài)切換的最佳姿勢

    這篇文章主要為大家詳細介紹一下SpringBoot實現(xiàn)數(shù)據(jù)源動態(tài)切換的最佳姿勢,文中的示例代碼講解詳細,感興趣的小伙伴可以跟隨小編一起學(xué)習(xí)一下
    2025-03-03
  • 一篇文章帶你入門java網(wǎng)絡(luò)編程

    一篇文章帶你入門java網(wǎng)絡(luò)編程

    網(wǎng)絡(luò)編程是指編寫運行在多個設(shè)備(計算機)的程序,這些設(shè)備都通過網(wǎng)絡(luò)連接起來。本文介紹了一些網(wǎng)絡(luò)編程基礎(chǔ)的概念,并用Java來實現(xiàn)TCP和UDP的Socket的編程,來讓讀者更好的了解其原理
    2021-08-08
  • 詳解spring cloud整合Swagger2構(gòu)建RESTful服務(wù)的APIs

    詳解spring cloud整合Swagger2構(gòu)建RESTful服務(wù)的APIs

    這篇文章主要介紹了詳解spring cloud整合Swagger2構(gòu)建RESTful服務(wù)的APIs,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2018-01-01
  • Java中的命名與目錄接口JNDI基本操作方法概覽

    Java中的命名與目錄接口JNDI基本操作方法概覽

    這篇文章主要介紹了Java中的命名與目錄接口JNDI基本操作方法概覽,JNDI提供統(tǒng)一的客戶端API使得Java應(yīng)用程序可以和這些命名服務(wù)和目錄服務(wù)之間進行交互,需要的朋友可以參考下
    2016-03-03
  • Java 給PPT添加動畫效果的示例

    Java 給PPT添加動畫效果的示例

    這篇文章主要介紹了Java 給PPT添加動畫效果的示例,幫助大家更好的理解和學(xué)習(xí)使用Java,感興趣的朋友可以了解下
    2021-04-04
  • Java常見延遲隊列的實現(xiàn)方案總結(jié)

    Java常見延遲隊列的實現(xiàn)方案總結(jié)

    Java延遲隊列(DelayQueue)是Java并發(fā)包中的一個類,它實現(xiàn)了BlockingQueue接口,且其中的元素必須實現(xiàn)Delayed接口,延遲隊列中的元素按照延遲時間的長短進行排序,本文給大家介紹了Java常見延遲隊列的實現(xiàn)方案總結(jié),需要的朋友可以參考下
    2024-03-03
  • 詳解java動態(tài)代理模式

    詳解java動態(tài)代理模式

    這篇文章主要為大家詳細介紹了java動態(tài)代理模式,總結(jié)一下代理模式,以及jdk,cglib代理模式用法,來理解代理模式,感興趣的小伙伴們可以參考一下
    2016-02-02
  • 代碼分析Spring MVC的工作原理

    代碼分析Spring MVC的工作原理

    在本篇文章里小編給大家整理了關(guān)于Spring MVC的工作原理的相關(guān)知識點以及實例代碼內(nèi)容,需要的朋友們可以參考下。
    2019-06-06

最新評論

浮梁县| 全南县| 中牟县| 措美县| 同心县| 镇雄县| 苍梧县| 延津县| 赤峰市| 三亚市| 嵊州市| 扶绥县| 新蔡县| 兴文县| 罗城| 长葛市| 建德市| 大渡口区| 福清市| 金川县| 甘肃省| 无锡市| 阿城市| 图木舒克市| 保亭| 利川市| 美姑县| 玉树县| 洞口县| 开化县| 陵川县| 甘肃省| 虞城县| 榆树市| 大连市| 喀什市| 海晏县| 桓台县| 彰武县| 晋中市| 揭西县|