Java 创建事件Event、事件监听EventListener、事件发布publishEvent
一、概述
個(gè)人認(rèn)為,事件機(jī)制一般可由:事件源source,事件對(duì)象Event,事件監(jiān)聽EventListener,事件發(fā)布publishEvent組成
事件源:引起事件發(fā)生的源; User用戶信息, Order訂單信息等為事件源數(shù)據(jù),User登錄狀態(tài)loginStatus引起的事件, Order狀態(tài)status引起的事件
事件對(duì)象:繼承ApplicationEvent,事件對(duì)象包含事件源,事件對(duì)象也就是要被監(jiān)聽的對(duì)象; UserEvent, OrderEvent為事件對(duì)象,
事件監(jiān)聽:監(jiān)聽事件對(duì)象,事件對(duì)象被發(fā)布觸發(fā)時(shí),事件監(jiān)聽到后執(zhí)行處理邏輯
事件發(fā)布:觸發(fā)事件的發(fā)生
發(fā)布事件publishEvent后,EventListener監(jiān)聽到進(jìn)行默認(rèn)同步處理, 線程被阻塞, 這種同步方式吞吐量小耗時(shí),不利用程序高并發(fā)。
在實(shí)際應(yīng)用過(guò)程中,事件發(fā)布或事件監(jiān)聽后處理邏輯應(yīng)該都是異步不阻塞線程。
publishEvent或EventListener 任意一個(gè)加上異步@Async即可(程序啟動(dòng)類必須要添加@EnableAsync)。推薦publishEvent加異步。
如果publishEven和EventListener過(guò)程中都有大量處理數(shù)據(jù)庫(kù)或其他耗時(shí)的業(yè)務(wù),也可以兩者同時(shí)加上@Async
.
舉例:
1.OrderEvent訂單事件中,用戶進(jìn)行訂單支付,訂單支付邏輯處理完,同步返回給用戶支付完成的消息,同時(shí)發(fā)布訂單事件,異步處理訂單發(fā)貨邏輯等,這樣可以將訂單支付和訂單發(fā)貨解耦。
2.UserEvent用戶事件中,用戶登錄成功后,同步返回給用戶登錄成功的消息,同時(shí)發(fā)布用戶登錄事件,異步處理用戶登錄后記日志登錄日志, 寫用戶購(gòu)物車緩存等邏輯
.
這種事件驅(qū)動(dòng)機(jī)制其實(shí)是觀察者模式(又稱發(fā)布訂閱)具體實(shí)現(xiàn),事件對(duì)象(Event)相當(dāng)于被觀察對(duì)象(Subject), 事件監(jiān)聽(EventListener) 相當(dāng)于觀察者(Observer)
下面是簡(jiǎn)單的代碼實(shí)現(xiàn)
二、創(chuàng)建事件源
package com.xxxx.model; import lombok.Data;@Data public class User {private Long id;private String loginStatus; } package com.xxxx.model; import lombok.Data;@Data public class Order {private Long id;private Integer status; }三、創(chuàng)建事件對(duì)象
例如:訂單狀態(tài)事件,用戶狀態(tài)事件, 需要繼承ApplicationEvent
package com.xxxx.event;import com.xxxx.model.Order; import org.springframework.context.ApplicationEvent;public class OrderEvent extends ApplicationEvent {private Order order;public OrderEvent(Order order) {//ApplicationEvent 構(gòu)造函數(shù)中必須傳入source對(duì)象, 官方注釋中被定義為最初發(fā)生事件的對(duì)象super(order);//方式二//super(order.getId());order = order;}public Order getOrder(){return order;} } package com.xxxx.event;import com.xxxx.model.User; import org.springframework.context.ApplicationEvent;public class UserEvent extends ApplicationEvent {private User user;public UserEvent(User user) {super(user);user = user;}public User getUser(){return user;} }四、事件監(jiān)聽
方法上添加監(jiān)聽事件的注解@EventListener
方法的參數(shù)為繼承ApplicationEvent的事件對(duì)象
五、事件發(fā)布
ApplicationContext應(yīng)用上下文繼承了ApplicationEventPublisher,可以調(diào)用發(fā)布事件
package com.xxxx.event;import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.ApplicationContext; import org.springframework.context.ApplicationEvent; import org.springframework.stereotype.Component;@Component public class EventPush {/*** ApplicationContext 繼承實(shí)現(xiàn)了 ApplicationEventPublisher, 可以直接發(fā)布事件*/@Autowiredprivate ApplicationContext applicationContext;@Asyncpublic void publishEvent(ApplicationEvent event){if (event instanceof OrderEvent) {applicationContext.publishEvent((OrderEvent) event);return;} else if(event instanceof UserEvent) {applicationContext.publishEvent((UserEvent) event);return;} else {//發(fā)布失敗}}@Asyncpublic void orderEventPush(OrderEvent event){applicationContext.publishEvent(event);}@Asyncpublic void userEventPush(UserEvent event){applicationContext.publishEvent(event);} }六、調(diào)用
注入依賴類
@Autowired private EventPush eventPush;調(diào)用事件發(fā)布
Order order = new Order(); order.setId(1000L); //0: 訂單創(chuàng)建成功 1:支付成功 ..... order.setStatus(1);User user = new User(); user.setId(1000L); //0: 退出成功 1:登錄成功 ..... user.setLoginStatus(1);//方式一: eventPush.orderEventPush(new OrderEvent(order)); eventPush.userEventPush(new UserEvent(user));//方式二: eventPush.publishEvent(new OrderEvent(order)); eventPush.publishEvent(new UserEvent(user));總結(jié)
以上是生活随笔為你收集整理的Java 创建事件Event、事件监听EventListener、事件发布publishEvent的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。