環境:Spring5.3.23
Spring事件機制是一種用于處理系統內部或者外部事件的機制,它是Spring框架的一部分。事件機制基于監聽者設計模式實現,包括事件、發布器和監聽器三個主要部分。
在Spring中,事件是主體,發布器負責發布事件,監聽器負責處理事件。事件對象封裝了事件源對象和事件相關信息,用于在事件源和監聽器之間傳遞信息。發布器通過注入事件發布者實現,使用事件發布者發布事件。監聽器通過實現ApplicationListener接口來定義,用于對事件進行處理。
Spring容器提供了事件管理機制,內部很多節點都會發布事件,也支持自定義事件。在Spring Boot中,你可以使用ApplicationEventPublisher接口來發布事件,通過繼承ApplicationEvent抽象類來定義事件對象,通過實現ApplicationListener接口來定義事件監聽器。
總之,Spring事件機制是一個非常有用的工具,可以幫助你更好地管理和處理系統中的事件。
創建并發布自己的自定義事件。通過ApplicationEvent
static class OrderEvent extends ApplicationEvent { private Order order ; public OrderEvent(Object source, Order order) { super(source) ; this.order = order ; } public Order getOrder() { return this.order; }}
要接收自定義 ApplicationEvent,可以創建一個實現 ApplicationListener 的類,并將其注冊為 Spring Bean。
static class OrderListener implements ApplicationListener<OrderEvent> { @Override public void onApplicationEvent(OrderEvent event) { System.out.printf("監聽到定義事件:%s", event.getOrder().toString()) ; }}
要發布自定義 ApplicationEvent,調用 ApplicationEventPublisher 上的 publishEvent() 方法。通常,可以通過創建一個實現 ApplicationEventPublisherAware 的類并將其注冊為 Spring Bean 來實現:
static class OrderService implements ApplicationEventPublisherAware { private ApplicationEventPublisher eventPublisher ; @Override public void setApplicationEventPublisher(ApplicationEventPublisher eventPublisher) { this.eventPublisher = eventPublisher ; } public void save(Order order) { this.eventPublisher.publishEvent(new OrderEvent("create oder event", new Order())); }}
你可以使用 @EventListener 注解在任意Bean 的任何方法上注冊事件監聽器。示例如下:
static class MyEventListener { @EventListener public void receiveOrderEvent(OrderEvent event) { System.out.printf("監聽到定義事件:%s", event.getOrder().toString()) ; } }
通過一個注解,實現了事件的監聽,在該方法中指定了要監聽的事件類型。
如果你的方法需要監聽多個事件,或者你想定義一個不帶任何參數的方法,也可以在注解中指定事件類型。示例如下:
@EventListener({OrderEvent.class, UserEvent.class})public void receiveOrderEvent() { System.out.printf("監聽到定義事") ;}
這里指明了只監聽OrderEvent, UserEvent兩個事件。
也可以直接通過ApplicationEvent攜帶參數,這樣可以通過判斷處理不同的事件類型,示例如下:
@EventListener({OrderEvent.class, UserEvent.class})public void receiveOrderEvent(ApplicationEvent event) { System.out.printf("監聽到定義事件:%s", event.getSource()) ;}
我們還可以通過SpEL表達式過濾事件,示例如下:
// User對象static class User { private Integer type ; public User(Integer type) { this.type = type ; }}// UserEvent事件對象static class UserEvent extends ApplicationEvent { private User user ; public UserEvent(Object source, User user) { super(source) ; this.user = user ; } public User getUser() { return user; }} // 事件監聽; 過濾只有User對象的type屬性為1時才會觸發事件@EventListener(condition = "#event.user.type == 1")public void receiveOrderEvent(UserEvent event) { System.out.printf("監聽到定義事件:%s", event.getUser()) ;}
異步方式1:
如果想讓某個監聽器異步處理事件,可以通過 @Async 注解支持,示例如下:
@EventListener@Asyncpublic void receiveOrderEvent(UserEvent event) { System.out.printf("%s - 監聽到定義事件:%s", Thread.currentThread().getName(), event.getUser()) ;}
執行結果:
SimpleAsyncTaskExecutor-1 - 監聽到定義事件:com.pack.main.events.EventMain$User@abb3dc
異步方式2:
自定義一個事件發布器
@Beanpublic SimpleApplicationEventMulticaster applicationEventMulticaster() { SimpleApplicationEventMulticaster applicationEventMulticaster = new SimpleApplicationEventMulticaster(); applicationEventMulticaster.setTaskExecutor(Executors.newSingleThreadExecutor()) ; return applicationEventMulticaster ;}
有個該事件發布器,容器在初始化時會先從容器中查找注冊的自定義發布器,源碼如下:
protected void initApplicationEventMulticaster() { ConfigurableListableBeanFactory beanFactory = getBeanFactory(); // 判斷容器中是否有beanName = applicationEventMulticaster 的Bean if (beanFactory.containsLocalBean(APPLICATION_EVENT_MULTICASTER_BEAN_NAME)) { this.applicationEventMulticaster = beanFactory.getBean(APPLICATION_EVENT_MULTICASTER_BEAN_NAME, ApplicationEventMulticaster.class); } else { // 如果不存在則注冊一個默認的,該默認的將使用默認的當前執行線程執行 this.applicationEventMulticaster = new SimpleApplicationEventMulticaster(beanFactory); beanFactory.registerSingleton(APPLICATION_EVENT_MULTICASTER_BEAN_NAME, this.applicationEventMulticaster); } }
執行結果:
pool-1-thread-1 - 監聽到定義事件:com.pack.main.events.EventMain$User@50f8a6
異步事件注意事項:
如果需要在調用一個監聽器之前調用另一個監聽器,可以在方法聲明中添加 @Order 注解,示例如下:
@EventListener@Order(1)public void receiveOrderEvent1(UserEvent event) { System.out.printf("%s - 監聽到定義事件 - 1:%s%n", Thread.currentThread().getName(), event.getUser()) ;}@EventListener@Order(0)public void receiveOrderEvent2(UserEvent event) { System.out.printf("%s - 監聽到定義事件 - 2:%s%n", Thread.currentThread().getName(), event.getUser()) ;}
@Order中指定的值越小優先級越高,執行結果如下:
main - 監聽到定義事件 - 2:com.pack.main.events.EventMain$User@96bacfmain - 監聽到定義事件 - 1:com.pack.main.events.EventMain$User@96bacf
完畢!!!
本文鏈接:http://www.www897cc.com/showinfo-26-16278-0.htmlSpring事件機制,深入剖析,提升你的技術水平!
聲明:本網頁內容旨在傳播知識,若有侵權等問題請及時與本網聯系,我們將在第一時間刪除處理。郵件:2376512515@qq.com
上一篇: Spring Boot應用中的配置文件選擇:YAML vs. Properties
下一篇: Go語言高級特性:Context深入解讀