亚洲乱码中文字幕综合,中国熟女仑乱hd,亚洲精品乱拍国产一区二区三区,一本大道卡一卡二卡三乱码全集资源,又粗又黄又硬又爽的免费视频

Spring Event觀察者模式事件監(jiān)聽(tīng)詳解

 更新時(shí)間:2022年08月18日 10:11:58   作者:llp1110  
這篇文章主要介紹了Java Spring Event事件監(jiān)聽(tīng)詳情解析,文章圍繞主題展開(kāi)詳細(xì)的內(nèi)容介紹,具有一定的參考價(jià)值,需要的小伙伴可以參考一下

Spring Event事件監(jiān)聽(tīng)

Spring Event(Application Event)其實(shí)就是一個(gè)觀察者設(shè)計(jì)模式,一個(gè) Bean 處理完成任務(wù)后希望通知其它 Bean 或者說(shuō)一個(gè) Bean 想觀察監(jiān)聽(tīng)另一個(gè)Bean 的行為。在開(kāi)發(fā)中我們經(jīng)常就會(huì)遇到修改一個(gè)bean時(shí),同時(shí)需要去修改其他得bean?;蛘哒f(shuō)當(dāng)一個(gè)bean得值發(fā)生變化時(shí),需要修改另一個(gè)bean得業(yè)務(wù)。還有一些業(yè)務(wù)場(chǎng)景不需要在一次請(qǐng)求中同步完成,比如郵件發(fā)送、短信發(fā)送等。

MQ 確實(shí)可以解決這個(gè)問(wèn)題,但 MQ比較重,非必要不提升架構(gòu)復(fù)雜度。因此Spring Event是非常好得選擇。

依賴:引入Spring得核心依賴即可

Spring Event同步使用

自定義事件

定義事件,繼承 ApplicationEvent 的類成為一個(gè)事件類:

@Data
public class OrderProductEvent extends ApplicationEvent {
  /** 該類型事件攜帶的信息 */
  private String orderId;
  public OrderProductEvent(Object source, String orderId) {
    super(source);
    this.orderId = orderId;
  }
}

定義監(jiān)聽(tīng)器

監(jiān)聽(tīng)并處理事件,實(shí)現(xiàn) ApplicationListener 接口或者使用 @EventListener 注解:

/**
 * 實(shí)現(xiàn) ApplicationListener 接口,并指定監(jiān)聽(tīng)的事件類型
 */
@Slf4j
@Component
public class OrderProductListener implements ApplicationListener<OrderProductEvent> {
  /**
   *  使用 onApplicationEvent 方法對(duì)消息進(jìn)行接收處理
   *  
   * */
  @SneakyThrows
  @Override
  public void onApplicationEvent(OrderProductEvent event) {
    String orderId = event.getOrderId();
    long start = System.currentTimeMillis();
    Thread.sleep(2000);
    long end = System.currentTimeMillis();
    log.info("{}:校驗(yàn)訂單商品價(jià)格耗時(shí):({})毫秒", orderId, (end - start));
  }
}

定義發(fā)布者

發(fā)布事件,通過(guò) ApplicationEventPublisher 發(fā)布事件:

@Slf4j
@Service
@RequiredArgsConstructor
public class OrderService {
  /** 注入ApplicationContext用來(lái)發(fā)布事件 */
  private final ApplicationContext applicationContext;
  /**
   * 下單
   *
   * @param orderId 訂單ID
   */
  public String buyOrder(String orderId) {
    long start = System.currentTimeMillis();
    // 1.查詢訂單詳情
    // 2.檢驗(yàn)訂單價(jià)格 (同步處理)
    applicationContext.publishEvent(new OrderProductEvent(this, orderId));
    long end = System.currentTimeMillis();
    log.info("任務(wù)全部完成,總耗時(shí):({})毫秒", end - start);
    return "購(gòu)買(mǎi)成功";
  }
}

測(cè)試執(zhí)行

@SpringBootTest
public class OrderServiceTest {
  @Autowired
  private OrderService orderService;
  @Test
  public void buyOrderTest() {
    orderService.buyOrder("732171109");
  }
}

c.l.l.event.OrderProductListener : 732171109:校驗(yàn)訂單商品價(jià)格耗時(shí):(2001)毫秒

c.llp.llpspringretry.event.OrderService : 任務(wù)全部完成,總耗時(shí):(2005)毫秒

Debug執(zhí)行流程

Spring Event 異步使用

有些業(yè)務(wù)場(chǎng)景不需要在一次請(qǐng)求中同步完成,比如郵件發(fā)送、短信發(fā)送等。

自定義事件

import lombok.AllArgsConstructor;
import lombok.Data;
@Data
@AllArgsConstructor
public class MsgEvent {
  /** 該類型事件攜帶的信息 */
  public String orderId;
}

定義監(jiān)聽(tīng)器

推薦使用 @EventListener 注解:

@Slf4j
@Component
public class MsgListener {
  @Async
  @SneakyThrows
  @EventListener(MsgEvent.class)
  public void sendMsg(MsgEvent event) {
    String orderId = event.getOrderId();
    long start = System.currentTimeMillis();
    log.info("開(kāi)發(fā)發(fā)送短信");
    log.info("開(kāi)發(fā)發(fā)送郵件");
    Thread.sleep(4000);
    long end = System.currentTimeMillis();
    log.info("{}:發(fā)送短信、郵件耗時(shí):({})毫秒", orderId, (end - start));
  }
}

定義發(fā)布者

@Slf4j
@Service
@RequiredArgsConstructor
public class OrderService {
  /** 注入ApplicationContext用來(lái)發(fā)布事件 */
  private final ApplicationContext applicationContext;
  /**
   * 下單
   *
   * @param orderId 訂單ID
   */
  public String buyOrder(String orderId) {
    long start = System.currentTimeMillis();
    // 1.查詢訂單詳情
    // 2.檢驗(yàn)訂單價(jià)格 (同步處理)
//    applicationContext.publishEvent(new OrderProductEvent(this, orderId));
    // 3.短信通知(異步處理) 新開(kāi)線程執(zhí)行監(jiān)聽(tīng)得業(yè)務(wù)
    applicationContext.publishEvent(new MsgEvent(orderId));
    long end = System.currentTimeMillis();
    log.info("任務(wù)全部完成,總耗時(shí):({})毫秒", end - start);
    return "購(gòu)買(mǎi)成功";
  }
}

開(kāi)啟異步支持

@EnableAsync開(kāi)啟異步支持

@EnableAsync
@EnableRetry
@SpringBootApplication
public class LlpSpringRetryApplication {
    public static void main(String[] args) {
        SpringApplication.run(LlpSpringRetryApplication.class, args);
    }
}

c.llp.llpspringretry.event.OrderService : 任務(wù)全部完成,總耗時(shí):(6)毫秒

c.llp.llpspringretry.event.MsgListener : 開(kāi)發(fā)發(fā)送短信

c.llp.llpspringretry.event.MsgListener : 開(kāi)發(fā)發(fā)送郵件

到此這篇關(guān)于Spring Event觀察者模式事件監(jiān)聽(tīng)詳解的文章就介紹到這了,更多相關(guān)Spring Event事件監(jiān)聽(tīng)內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • Java中的阻塞隊(duì)列BlockingQueue使用詳解

    Java中的阻塞隊(duì)列BlockingQueue使用詳解

    這篇文章主要介紹了Java中的阻塞隊(duì)列BlockingQueue使用詳解,阻塞隊(duì)列是一種線程安全的數(shù)據(jù)結(jié)構(gòu),用于在多線程環(huán)境下進(jìn)行數(shù)據(jù)交換,它提供了一種阻塞的機(jī)制,當(dāng)隊(duì)列為空時(shí),消費(fèi)者線程將被阻塞,直到隊(duì)列中有數(shù)據(jù)可供消費(fèi),需要的朋友可以參考下
    2023-10-10
  • SpringBoot + minio實(shí)現(xiàn)分片上傳、秒傳、續(xù)傳功能

    SpringBoot + minio實(shí)現(xiàn)分片上傳、秒傳、續(xù)傳功能

    MinIO是一個(gè)基于Go實(shí)現(xiàn)的高性能、兼容S3協(xié)議的對(duì)象存儲(chǔ),使用MinIO構(gòu)建用于機(jī)器學(xué)習(xí),分析和應(yīng)用程序數(shù)據(jù)工作負(fù)載的高性能基礎(chǔ)架構(gòu),這篇文章主要介紹了SpringBoot + minio實(shí)現(xiàn)分片上傳、秒傳、續(xù)傳,需要的朋友可以參考下
    2023-06-06
  • java substring(a)與substring(a,b)的使用說(shuō)明

    java substring(a)與substring(a,b)的使用說(shuō)明

    這篇文章主要介紹了java substring(a)與substring(a,b)的使用說(shuō)明,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧
    2020-10-10
  • java中ThreadLocalRandom的使用詳解

    java中ThreadLocalRandom的使用詳解

    這篇文章主要介紹了java中ThreadLocalRandom的使用詳解,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2020-03-03
  • java實(shí)現(xiàn)網(wǎng)站微信掃碼支付

    java實(shí)現(xiàn)網(wǎng)站微信掃碼支付

    這篇文章主要為大家詳細(xì)介紹了java實(shí)現(xiàn)網(wǎng)站微信掃碼支付,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2018-07-07
  • java程序運(yùn)行時(shí)內(nèi)存分配詳解

    java程序運(yùn)行時(shí)內(nèi)存分配詳解

    這篇文章主要介紹了java程序運(yùn)行時(shí)內(nèi)存分配詳解 ,需要的朋友可以參考下
    2016-07-07
  • Python基礎(chǔ)之如何使用multiprocessing模塊

    Python基礎(chǔ)之如何使用multiprocessing模塊

    今天帶大家學(xué)習(xí)python多進(jìn)程的相關(guān)知識(shí),文中對(duì)multiprocessing模塊的使用作了非常詳細(xì)的介紹,需要的朋友可以參考下
    2021-06-06
  • Java全能工具類之Hutool的用法詳解

    Java全能工具類之Hutool的用法詳解

    Hutool是一個(gè)Java工具類庫(kù),由國(guó)內(nèi)的程序員loolly開(kāi)發(fā),目的是提供一些方便、快捷、實(shí)用的工具類和工具方法,本文就來(lái)詳細(xì)聊聊它的使用吧
    2023-03-03
  • MyBatis映射文件中的動(dòng)態(tài)SQL實(shí)例詳解

    MyBatis映射文件中的動(dòng)態(tài)SQL實(shí)例詳解

    在本文中,我們深入探討了動(dòng)態(tài)SQL的各種標(biāo)簽,包括<if>、<choose>、<trim>、<foreach>等,通過(guò)實(shí)際的例子演示了它們的用法,感興趣的朋友一起揭開(kāi)動(dòng)態(tài)SQL的神秘面紗,帶你領(lǐng)略它的魅力
    2024-01-01
  • Java源碼解析之接口List

    Java源碼解析之接口List

    今天帶大家復(fù)習(xí)Java基礎(chǔ)的一些知識(shí)點(diǎn),對(duì)接口List進(jìn)行了詳細(xì)的解析,對(duì)正在學(xué)習(xí)Java的小伙伴們有很好地幫助,需要的朋友可以參考下
    2021-05-05

最新評(píng)論