spring事件發送監聽由3個部分組成
1.ApplicationEvent:表示事件本身,自定義事件需要繼承該類
2.ApplicationEventPublisherAware:事件發送器,需要實現該接口
3.ApplicationListener<T>:事件監聽器接口
注意!默認情況下是同步的,事件被publish後會等待Listener的處理
以下是實現代碼
ApplicationEvent
public class MessageEvent extends ApplicationEvent {
public MessageEvent(Object source) {
super(source);
}
}
ApplicationEventPublisherAware
@Component
public class EventPublisher implements ApplicationEventPublisherAware {
private static ApplicationEventPublisher applicationEventPublisher;
public void setApplicationEventPublisher(ApplicationEventPublisher applicationEventPublisher) {
EventPublisher.applicationEventPublisher = applicationEventPublisher;
}
public static void publishEvent(ApplicationEvent applicationEvent) {
applicationEventPublisher.publishEvent(applicationEvent);
}
}
ApplicationListener<T>,在監聽中sleep一會,使同步現象更明顯,在調用publishEvent後有更明顯的停頓
@Component
public class MessageEventListener implements ApplicationListener<MessageEvent> {
public void onApplicationEvent(MessageEvent messageEvent) {
try {
Thread.sleep(10000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("i got messageEvent");
}
}
1.添加@Asycn註解
2.使用task標籤使註解生效
3.配置executor
@Component
public class MessageEventListener implements ApplicationListener<MessageEvent> {
@Async
public void onApplicationEvent(MessageEvent messageEvent) {
try {
Thread.sleep(10000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("i got messageEvent");
}
}
xml
<task:annotation-driven/>
<task:executor id="executor" keep-alive="1000" pool-size="20" queue-capacity="20" rejection-policy="ABORT"/>
<task:executor>配置參數:
id:當配置多個executor時,被@Async("id")指定使用;也被作爲線程名的前綴。
pool-size:線程數數
queue-capacity:當最小的線程數已經被佔用滿後,新的任務會被放進queue裏面,當這個 queue的capacity也被佔滿之後,pool裏面會創建新線程處理這個任務,直到總線程數達到了max size,這時系統會拒絕這個任務並拋出TaskRejectedException異常(缺省配置的情況下,可以通過rejection-policy 來決定如何處理這種情況)
keep-alive:超過size的那些線程,任務完成後,再經過這個時長(秒)會被結束掉
rejection-policy:當pool已經達到size的時候,如何處理新任務
ABORT(缺省):拋出TaskRejectedException異常,然後不執行
DISCARD:不執行,也不拋出異常
DISCARD_OLDEST:丟棄queue中最舊的那個任務
CALLER_RUNS:不在新線程中執行任務,而是有調用者所在的線程來執行