javascript
Spring5参考指南:事件Event
文章目錄
- 基于繼承的Event
- 基于注解的Event
- 異步偵聽器
Spring提供了很方便的事件的處理機制,包括事件類ApplicationEvent和事件監聽類ApplicationListener。 他實現的是設計者模式,如果實現了ApplicationListener接口的bean部署到Spring容器中,則每次ApplicationEvent發布到ApplicationContext時,都會通知該bean。
從Spring4.2開始,提供了基于注解的事件,即事件對象不一定要從ApplicationEvent來擴展。Spring會自動將其封裝成一個事件對象。
下面是Spring的標準事件描述:
| ContextRefreshedEvent | 在初始化或刷新ApplicationContext時發布(例如,通過在ConfigurableApplicationContext接口上使用refresh()方法)。這里,“初始化”意味著加載所有bean,檢測并激活后處理器bean,預先實例化單例,并且ApplicationContext對象準備好使用。只要上下文未關閉,只要所選的ApplicationContext實際上支持此類“熱”刷新,就可以多次觸發刷新。例如,XMLWebApplicationContext支持熱刷新,但GenericApplicationContext不支持。 |
| ContextStartedEvent | 在可配置的ApplicationContext接口上使用start()方法啟動ApplicationContext時發布。這里,“啟動”意味著所有生命周期bean都會收到一個顯式的啟動信號。通常,此信號用于在顯式停止后重新啟動bean,但也可以用于啟動尚未配置為自動啟動的組件(例如,初始化時尚未啟動的組件)。 |
| ContextStoppedEvent | 在可配置的ApplicationContext接口上使用stop()方法停止ApplicationContext時發布。這里,“停止”意味著所有生命周期bean都會收到一個明確的停止信號。停止的上下文可以通過start()調用重新啟動。 |
| ContextClosedEvent | 在可配置的ApplicationContext接口上使用close()方法關閉ApplicationContext時發布。這里,“關閉”意味著所有的單例beans都被銷毀了。封閉的環境達到了生命的盡頭。無法刷新或重新啟動。 |
| RequestHandledEvent | 一個特定于Web的事件,告訴所有bean HTTP請求已被服務。此事件在請求完成后發布。此事件僅適用于使用Spring的DispatcherServlet的Web應用程序。 |
基于繼承的Event
你也可以自定義事件,下面是一個繼承ApplicationEvent的例子:
public class BlackListEvent extends ApplicationEvent {private final String address;private final String content;public BlackListEvent(Object source, String address, String content) {super(source);this.address = address;this.content = content;} }若要發布自定義ApplicationEvent,在ApplicationEventPublisher上調用PublishEvent()方法。通??梢酝ㄟ^實現ApplicationEventPublisherAware接口來實現,如下所示:
public class EmailService implements ApplicationEventPublisherAware {private List<String> blackList;private ApplicationEventPublisher publisher;public void setBlackList(List<String> blackList) {this.blackList = blackList;}public void setApplicationEventPublisher(ApplicationEventPublisher publisher) {this.publisher = publisher;}public void sendEmail(String address, String content) {if (blackList.contains(address)) {publisher.publishEvent(new BlackListEvent(this, address, content));return;}} }在配置時,Spring容器檢測到EmailService實現了ApplicationEventPublisherAware,并自動調用setApplicationEventPublisher()。實際上,傳入的參數是Spring容器本身。您正在通過其applicationEventPublisher接口與應用程序上下文進行交互。
要接收定制的applicationEvent,可以創建一個實現applicationListener的類,并將其注冊為SpringBean。下面的示例顯示了這樣的類:
public class BlackListNotifier implements ApplicationListener<BlackListEvent> {private String notificationAddress;public void setNotificationAddress(String notificationAddress) {this.notificationAddress = notificationAddress;}public void onApplicationEvent(BlackListEvent event) {// notify appropriate parties via notificationAddress...} }這里使用了ApplicationListener 的BlackListEvent泛型。意味著onApplicationEvent()方法可以保持類型安全,避免任何向下強制轉換的需要。
但請注意,默認情況下,事件偵聽器同步接收事件。這意味著publishEvent()方法將一直阻塞,直到所有偵聽器完成對事件的處理。
下面是注冊和配置bean的例子:
<bean id="emailService" class="example.EmailService"><property name="blackList"><list><value>known.spammer@example.org</value><value>known.hacker@example.org</value><value>john.doe@example.org</value></list></property> </bean><bean id="blackListNotifier" class="example.BlackListNotifier"><property name="notificationAddress" value="blacklist@example.org"/> </bean>Spring的事件機制是為同一應用程序上下文中SpringBean之間的簡單通信而設計的。對于更復雜的企業集成需求,可以使用Spring Integration的AMQP模型來處理。
基于注解的Event
從Spring4.2開始,您可以使用EventListener注解在托管bean的任何公共方法上注冊事件偵聽器。BlackListNotifier程序可以改寫如下:
public class BlackListNotifierAnnotation {private String notificationAddress;public void setNotificationAddress(String notificationAddress) {this.notificationAddress = notificationAddress;}@EventListenerpublic void processBlackListEvent(BlackListEvent event) {// notify appropriate parties via notificationAddress...} }如果您的方法應該監聽多個事件,或者您想要定義它而不使用任何參數,那么也可以在注解本身上指定事件類型。以下示例顯示了如何執行此操作:
@EventListener({ContextStartedEvent.class, ContextRefreshedEvent.class})public void handleContextStart() {}還可以使用定義spEL表達式的注解的條件屬性添加其他運行時篩選,該表達式應與實際調用特定事件的方法相匹配。
下面的例子顯示了如何重寫通知程序,以便僅在事件的內容屬性等于my-event時調用:
@EventListener(condition = "#blEvent.content == 'my-event'")public void processBlackListSPELEvent(BlackListEvent blEvent) {// notify appropriate parties via notificationAddress...}下表列出了上下文可用的項,以便您可以將它們用于條件事件處理:
| Event | root object | 真實的ApplicationEvent | #root.event |
| Arguments array | root object | 調用目標的參數 | #root.args[0] |
| Argument name | evaluation context | 任何方法參數的名稱。如果由于某種原因,名稱不可用(例如,因為沒有調試信息),參數名稱也可以在 #a<#arg>下使用,其中#arg表示參數索引(從0開始)。 | #blEvent or #a0 (也可以使用 #p0 or #p<#arg>) |
異步偵聽器
如果希望特定的偵聽器異步處理事件,可以重用常規的@Async支持。下面是@Async的例子:
@Async@EventListenerpublic void processBlackListEvent(BlackListEvent event) {// notify appropriate parties via notificationAddress...}Listeners排序
如果需要先調用一個監聽器,然后再調用另一個監聽器,則可以將@order注解添加到方法聲明中,如下所示:
@EventListener@Order(12)public void processBlackListEvent(BlackListEvent event) {// notify appropriate parties via notificationAddress...}本文的例子可以參考: event
更多精彩內容且看:
- 區塊鏈從入門到放棄系列教程-涵蓋密碼學,超級賬本,以太坊,Libra,比特幣等持續更新
- Spring Boot 2.X系列教程:七天從無到有掌握Spring Boot-持續更新
- Spring 5.X系列教程:滿足你對Spring5的一切想象-持續更新
- java程序員從小工到專家成神之路(2020版)-持續更新中,附詳細文章教程
更多教程請參考flydean的博客
總結
以上是生活随笔為你收集整理的Spring5参考指南:事件Event的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Spring5参考指南:Environm
- 下一篇: Spring5参考指南: Resourc