Spring 事件機制
1.1 核心概念
1.1.1 事件(Event)
- 事件是繼承自 ApplicationEvent 的類,用於封裝需要傳遞的資訊。
- 事件通常是自定義的,表示某種特定的動作或狀態變化。
import org.springframework.context.ApplicationEvent;
public class MyCustomEvent extends ApplicationEvent {
private final String message;
public MyCustomEvent(Object source, String message) {
super(source);
this.message = message;
}
public String getMessage() {
return message;
}
}
1.1.2 事件釋出者(Publisher)
- 使用 ApplicationEventPublisher 釋出事件。
- Spring 的任何 Bean 都可以是一個事件釋出者。
import org.springframework.context.ApplicationEventPublisher;
import org.springframework.stereotype.Component;
@Component
public class MyEventPublisher {
private final ApplicationEventPublisher publisher;
public MyEventPublisher(ApplicationEventPublisher publisher) {
this.publisher = publisher;
}
public void publishEvent(String message) {
MyCustomEvent event = new MyCustomEvent(this, message);
publisher.publishEvent(event);
}
}
1.1.3 事件監聽器(Listener)
- 使用 @EventListener 或實現 ApplicationListener 介面來監聽事件。
- 當事件被觸發時,監聽器會執行對應的邏輯。
基於註解的監聽器:
import org.springframework.context.event.EventListener;
import org.springframework.stereotype.Component;
@Component
public class MyEventListener {
@EventListener
public void handleMyCustomEvent(MyCustomEvent event) {
System.out.println("Received event - " + event.getMessage());
}
}
實現介面的監聽器:
import org.springframework.context.ApplicationListener;
import org.springframework.stereotype.Component;
@Component
public class MyEventListener implements ApplicationListener<MyCustomEvent> {
@Override
public void onApplicationEvent(MyCustomEvent event) {
System.out.println("Received event - " + event.getMessage());
}
}
1.2 事件機制流程
- 事件釋出者呼叫 publishEvent() 釋出一個事件。
- Spring 的事件廣播器(SimpleApplicationEventMulticaster)負責將事件分發給所有符合條件的監聽器。
- 監聽器接收到事件並執行對應的處理邏輯。
1.3 實際應用場景
- 解耦業務邏輯:比如,使用者註冊成功後傳送歡迎郵件和日誌記錄,兩個操作透過事件機制解耦。
- 應用狀態變化通知:系統中某個模組狀態變化時,通知其他模組執行相關處理。
- 非同步事件處理:Spring 事件機制支援非同步事件處理(透過執行緒池)。
@Component
public class AsyncEventListener {
@EventListener
@Async
public void handleEvent(MyCustomEvent event) {
System.out.println("Processing event asynchronously: " + event.getMessage());
}
}
1.4 常見注意事項
- 預設情況下,事件監聽器在同一個執行緒中執行,可以透過 @Async 實現非同步。
- 自定義事件必須繼承 ApplicationEvent(Spring 4.2+ 不強制要求,但推薦這樣做)。
- 釋出事件的元件需要被 Spring 容器管理。