觀察者模式JAVA,Spring中的觀察者模式

 2023-10-18 阅读 29 评论 0

摘要:一、Spring中觀察者模式的四個角色 1.事件(ApplicationEvent) 觀察者模式JAVA。ApplicationEvent 是所有事件對象的父類。ApplicationEvent 繼承自 jdk 的 EventObject, 所有的事件都需要繼承 ApplicationEvent, 并且通過source得到事件源。 下列描述了Spring提

一、Spring中觀察者模式的四個角色

1.事件(ApplicationEvent)

觀察者模式JAVA。ApplicationEvent 是所有事件對象的父類。ApplicationEvent 繼承自 jdk 的 EventObject, 所有的事件都需要繼承 ApplicationEvent, 并且通過source得到事件源。

下列描述了Spring提供的內置事件:

  • ContextRefreshedEvent:事件發布在 ApplicationContext 初始化或刷新時(例如:通過在 ConfigurableApplicationContext 接口使用refresh()方法)。這里,“初始化”意味著所有 bean 加載,post-processor bean 被檢測到并且激活,單例預先實例化,ApplicationContext 對象可以使用了。只要上下文沒有關閉,可以觸發多次刷新, ApplicationContext 提供了一種可選擇的支持這種“熱”刷新。例如:XmlWebApplicationContext 支持熱刷新,但 GenericApplicationContext 并非如此。具體是在 AbstractApplicationContext 的 finishRefresh() 方法中。
  • ContextStartedEvent:事件發布在 ApplicationContext 開始使用 ConfigurableApplicationContext 接口 start() 方法。這里,“開始”意味著所有生命周期 bean 接收到一個明確的起始信號。通常,這個信號用于明確停止后重新啟動,但它也可以用于啟動組件沒有被配置為自動運行(例如:組件還沒有開始初始化)。
  • ContextStoppedEvent:事件發布在 ApplicationContext 停止時通過使用 ConfigurableApplicationContext 接口上的 stop() 方法。在這里,“停止”意味著所有生命周期bean接收一個顯式的停止信號。停止上下文可以通過重新調用start()方法。
  • ContextClosedEvent:事件發布在 ApplicationContext 關閉時通過關閉 ConfigurableApplicationContext 接口()方法。這里,“封閉”意味著所有單例 bean 被摧毀。一個封閉的環境達到生命的終結。它不能刷新或重啟。
  • RequestHandledEvent:一個特定的web事件告訴所有能處理HTTP請求的bean 。這個事件是在請求完成后發布的。這個事件只適用于使用 Spring 的 DispatcherServlet 的web應用程序。

2.事件監聽(ApplicationListener)

ApplicationListener 事件監聽器,也就是觀察者。繼承自 jdk 的 EventListener,該類中只有一個方法 onApplicationEvent。當監聽的事件發生后該方法會被執行。

3.事件發布(ApplicationContext)

ApplicationContext 是 Spring 中的核心容器,在事件監聽中 ApplicationContext 可以作為事件的發布者,也就是事件源。因為 ApplicationContext 繼承自 ApplicationEventPublisher。在 ApplicationEventPublisher 中定義了事件發布的方法 — publishEvent(Object event)

4.事件管理(ApplicationEventMulticaster)

ApplicationEventMulticaster 用于事件監聽器的注冊和事件的廣播。監聽器的注冊就是通過它來實現的,它的作用是把 Applicationcontext 發布的 Event 廣播給它的監聽器列表。

二、Spring中實現觀察者模式

  1. 自定義需要發布的事件類,需要繼承 ApplicationEvent 類或 PayloadApplicationEvent (該類也僅僅是對 ApplicationEvent 的一層封裝)
  2. 使用 @EventListener 來監聽事件或者實現 ApplicationListener 接口。
  3. 使用 ApplicationEventPublisher 來發布自定義事件(@Autowired注入即可)

@TransactionalEventListener 監聽器:如果事件的發布不是在事務(@Transactional)范圍內,則監聽不到該事件,除非將 fallbackExecution 標志設置為 true(@TransactionalEventListener(fallbackExecution = true));如果在事務中,可以選擇在事務的哪個階段來監聽事件,默認在事務提交后監聽(@TransactionalEventListener(phase = TransactionPhase.AFTER_COMPLETION))。

以上介紹的事件監聽都是同步,如果需要開啟異步支持的話:

@Configuration
@EnableAsync
public class AsyncEventConfiguration implements AsyncConfigurer {@Overridepublic Executor getAsyncExecutor() {return Executors.newCachedThreadPool();}
}

三、 實戰

事件(MyEvent.java)

@Component
public class MyEvent extends ApplicationEvent {public MyEvent(ApplicationContext source) {super(source);System.out.println("MyEvent 構造器執行");}public void echo() {System.out.println("模擬業務邏輯執行");}
}

事件監聽(MyListenerA.java、MyListenerB.java)

@Component
public class MyListenerA implements ApplicationListener<MyEvent> {@Overridepublic void onApplicationEvent(MyEvent myEvent) {System.out.println("MyListenerA");myEvent.echo();}
}
@Component
public class MyListenerB {@EventListenerpublic void onApplicationEvent(MyEvent myEvent) {System.out.println("MyListenerB");myEvent.echo();}}

事件發布(MyPublisher.java)

@Component
public class MyPublisher implements ApplicationContextAware {private ApplicationContext applicationContext;@Overridepublic void setApplicationContext(ApplicationContext applicationContext) throws BeansException {this.applicationContext = applicationContext;}/*** 發布事件* 監聽該事件的監聽者都可以獲取消息** @param myEvent*/public void publisherEvent(MyEvent myEvent) {System.out.println("---開始發布 myEvent 事件---");applicationContext.publishEvent(myEvent);}
}

單元測試

@RunWith(SpringRunner.class)
@SpringBootTest
public class DesignPatternsApplicationTests {@Autowiredprivate MyPublisher myPublisher;@Autowiredprivate MyEvent myEvent;@Testpublic void contextLoads() {myPublisher.publisherEvent(myEvent);}
}

演示源代碼 :https://github.com/JMCuixy/design-patterns/tree/master/src/main/java/com/example/observer/spring

轉載于:https://www.cnblogs.com/jmcui/p/11054756.html

版权声明:本站所有资料均为网友推荐收集整理而来,仅供学习和研究交流使用。

原文链接:https://hbdhgg.com/1/149241.html

发表评论:

本站为非赢利网站,部分文章来源或改编自互联网及其他公众平台,主要目的在于分享信息,版权归原作者所有,内容仅供读者参考,如有侵权请联系我们删除!

Copyright © 2022 匯編語言學習筆記 Inc. 保留所有权利。

底部版权信息