Spring Event觀察者模式事件監(jiān)聽詳解
Spring Event事件監(jiān)聽
Spring Event(Application Event)其實就是一個觀察者設計模式,一個 Bean 處理完成任務后希望通知其它 Bean 或者說一個 Bean 想觀察監(jiān)聽另一個Bean 的行為。在開發(fā)中我們經(jīng)常就會遇到修改一個bean時,同時需要去修改其他得bean。或者說當一個bean得值發(fā)生變化時,需要修改另一個bean得業(yè)務。還有一些業(yè)務場景不需要在一次請求中同步完成,比如郵件發(fā)送、短信發(fā)送等。
MQ 確實可以解決這個問題,但 MQ比較重,非必要不提升架構復雜度。因此Spring Event是非常好得選擇。
依賴:引入Spring得核心依賴即可
Spring Event同步使用
自定義事件
定義事件,繼承 ApplicationEvent 的類成為一個事件類:
@Data public class OrderProductEvent extends ApplicationEvent { /** 該類型事件攜帶的信息 */ private String orderId; public OrderProductEvent(Object source, String orderId) { super(source); this.orderId = orderId; } }
定義監(jiān)聽器
監(jiān)聽并處理事件,實現(xiàn) ApplicationListener 接口或者使用 @EventListener 注解:
/** * 實現(xiàn) ApplicationListener 接口,并指定監(jiān)聽的事件類型 */ @Slf4j @Component public class OrderProductListener implements ApplicationListener<OrderProductEvent> { /** * 使用 onApplicationEvent 方法對消息進行接收處理 * * */ @SneakyThrows @Override public void onApplicationEvent(OrderProductEvent event) { String orderId = event.getOrderId(); long start = System.currentTimeMillis(); Thread.sleep(2000); long end = System.currentTimeMillis(); log.info("{}:校驗訂單商品價格耗時:({})毫秒", orderId, (end - start)); } }
定義發(fā)布者
發(fā)布事件,通過 ApplicationEventPublisher 發(fā)布事件:
@Slf4j @Service @RequiredArgsConstructor public class OrderService { /** 注入ApplicationContext用來發(fā)布事件 */ private final ApplicationContext applicationContext; /** * 下單 * * @param orderId 訂單ID */ public String buyOrder(String orderId) { long start = System.currentTimeMillis(); // 1.查詢訂單詳情 // 2.檢驗訂單價格 (同步處理) applicationContext.publishEvent(new OrderProductEvent(this, orderId)); long end = System.currentTimeMillis(); log.info("任務全部完成,總耗時:({})毫秒", end - start); return "購買成功"; } }
測試執(zhí)行
@SpringBootTest public class OrderServiceTest { @Autowired private OrderService orderService; @Test public void buyOrderTest() { orderService.buyOrder("732171109"); } }
c.l.l.event.OrderProductListener : 732171109:校驗訂單商品價格耗時:(2001)毫秒
c.llp.llpspringretry.event.OrderService : 任務全部完成,總耗時:(2005)毫秒
Debug執(zhí)行流程
Spring Event 異步使用
有些業(yè)務場景不需要在一次請求中同步完成,比如郵件發(fā)送、短信發(fā)送等。
自定義事件
import lombok.AllArgsConstructor; import lombok.Data; @Data @AllArgsConstructor public class MsgEvent { /** 該類型事件攜帶的信息 */ public String orderId; }
定義監(jiān)聽器
推薦使用 @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("開發(fā)發(fā)送短信"); log.info("開發(fā)發(fā)送郵件"); Thread.sleep(4000); long end = System.currentTimeMillis(); log.info("{}:發(fā)送短信、郵件耗時:({})毫秒", orderId, (end - start)); } }
定義發(fā)布者
@Slf4j @Service @RequiredArgsConstructor public class OrderService { /** 注入ApplicationContext用來發(fā)布事件 */ private final ApplicationContext applicationContext; /** * 下單 * * @param orderId 訂單ID */ public String buyOrder(String orderId) { long start = System.currentTimeMillis(); // 1.查詢訂單詳情 // 2.檢驗訂單價格 (同步處理) // applicationContext.publishEvent(new OrderProductEvent(this, orderId)); // 3.短信通知(異步處理) 新開線程執(zhí)行監(jiān)聽得業(yè)務 applicationContext.publishEvent(new MsgEvent(orderId)); long end = System.currentTimeMillis(); log.info("任務全部完成,總耗時:({})毫秒", end - start); return "購買成功"; } }
開啟異步支持
@EnableAsync開啟異步支持
@EnableAsync @EnableRetry @SpringBootApplication public class LlpSpringRetryApplication { public static void main(String[] args) { SpringApplication.run(LlpSpringRetryApplication.class, args); } }
c.llp.llpspringretry.event.OrderService : 任務全部完成,總耗時:(6)毫秒
c.llp.llpspringretry.event.MsgListener : 開發(fā)發(fā)送短信
c.llp.llpspringretry.event.MsgListener : 開發(fā)發(fā)送郵件
到此這篇關于Spring Event觀察者模式事件監(jiān)聽詳解的文章就介紹到這了,更多相關Spring Event事件監(jiān)聽內容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!
相關文章
SpringBoot + minio實現(xiàn)分片上傳、秒傳、續(xù)傳功能
MinIO是一個基于Go實現(xiàn)的高性能、兼容S3協(xié)議的對象存儲,使用MinIO構建用于機器學習,分析和應用程序數(shù)據(jù)工作負載的高性能基礎架構,這篇文章主要介紹了SpringBoot + minio實現(xiàn)分片上傳、秒傳、續(xù)傳,需要的朋友可以參考下2023-06-06java substring(a)與substring(a,b)的使用說明
這篇文章主要介紹了java substring(a)與substring(a,b)的使用說明,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧2020-10-10Python基礎之如何使用multiprocessing模塊
今天帶大家學習python多進程的相關知識,文中對multiprocessing模塊的使用作了非常詳細的介紹,需要的朋友可以參考下2021-06-06