成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

別再面向for循環編程了,Spring自帶的觀察者模式就很香!

開發 后端
不用再面試 for 循環編程了,Spring 框架自帶的事件監聽機制,實現觀察者模式、實現解耦輕松幫你全搞定!

 [[393113]]

分享下如何在 Spring/ Spring Boot 中實現觀察者模式。

不用再面試 for 循環編程了,Spring 框架自帶的事件監聽機制,實現觀察者模式、實現解耦輕松幫你全搞定!

Spring 事件監聽機制

其實在 Spring/ Spring Boot 框架中有一套事件監聽機制,可以實現觀察者模式。

Spring/ Spring Boot 框架中也都內置了許多事件,我們也可以自定義發布應用程序事件,下面我們會介紹。

其主要涉及到的幾個核心類和接口如下 :

ApplicationEvent

ApplicationEvent(應用程序事件)它是一個抽象類,相當于觀察者模式中的觀察目標。

ApplicationEvent 源碼如下: 

  1. public abstract class ApplicationEvent extends EventObject {  
  2.    /** use serialVersionUID from Spring 1.2 for interoperability. */  
  3.    private static final long serialVersionUID = 7099057708183571937L 
  4.    /** System time when the event happened. */  
  5.    private final long timestamp;  
  6.    /**  
  7.     * Create a new {@code ApplicationEvent}.  
  8.     * @param source the object on which the event initially occurred or with  
  9.     * which the event is associated (never {@code null})  
  10.     */  
  11.    public ApplicationEvent(Object source) {  
  12.       super(source);  
  13.       this.timestamp = System.currentTimeMillis();  
  14.    }  
  15.    /**  
  16.     * Return the system time in milliseconds when the event occurred.  
  17.     */  
  18.    public final long getTimestamp() {  
  19.       return this.timestamp;  
  20.    }  

ApplicationEvent 繼承自 Java 中的 EventObject 事件對象類,Spring 框架中的所有事件都繼承自 ApplicationEvent 類,它是所有事件的父類。

ApplicationEvent 主要的核心是類構造器,它可以初始化一個 source 事件關聯對象,以便在事件監聽器中獲取并通知更新。

ApplicationListener

ApplicationListener(應用程序事件監聽器)它是一個接口,相當于觀察者模式中的觀察者。

ApplicationListener 源碼如下: 

  1. public interface ApplicationListener<E extends ApplicationEvent> extends EventListener {  
  2.    /**  
  3.     * Handle an application event.  
  4.     * @param event the event to respond to  
  5.     */  
  6.    void onApplicationEvent(E event);  

ApplicationListener 繼承自 Java 中的 EventListener 事件監聽接口,ApplicationListener 類中只有一個 onApplicationEvent 方法,當指定監聽的事件被發布后就會被觸發執行,可以通過 event 獲取事件中的關聯對象。

ApplicationEventPublisher

應用程序事件發布接口,封裝了事件發布功能的基礎接口。 

  1. public interface ApplicationEventPublisher {  
  2.    /**  
  3.     * Notify all <strong>matching</strong> listeners registered with this  
  4.     * application of an application event. Events may be framework events  
  5.     * (such as ContextRefreshedEvent) or application-specific events.  
  6.     * <p>Such an event publication step is effectively a hand-off to the  
  7.     * multicaster and does not imply synchronous/asynchronous execution  
  8.     * or even immediate execution at all. Event listeners are encouraged  
  9.     * to be as efficient as possible, individually using asynchronous  
  10.     * execution for longer-running and potentially blocking operations.  
  11.     * @param event the event to publish  
  12.     * @see #publishEvent(Object)  
  13.     * @see org.springframework.context.event.ContextRefreshedEvent  
  14.     * @see org.springframework.context.event.ContextClosedEvent  
  15.     */  
  16.    default void publishEvent(ApplicationEvent event) {  
  17.       publishEvent((Object) event);  
  18.    }  
  19.    /**  
  20.     * Notify all <strong>matching</strong> listeners registered with this  
  21.     * application of an event. 
  22.     * <p>If the specified {@code event} is not an {@link ApplicationEvent},  
  23.     * it is wrapped in a {@link PayloadApplicationEvent}.  
  24.     * <p>Such an event publication step is effectively a hand-off to the  
  25.     * multicaster and does not imply synchronous/asynchronous execution  
  26.     * or even immediate execution at all. Event listeners are encouraged  
  27.     * to be as efficient as possible, individually using asynchronous  
  28.     * execution for longer-running and potentially blocking operations.  
  29.     * @param event the event to publish  
  30.     * @since 4.2  
  31.     * @see #publishEvent(ApplicationEvent)  
  32.     * @see PayloadApplicationEvent  
  33.     */  
  34.    void publishEvent(Object event);  

ApplicationEventPublisher 有一個默認接口方法和接口方法,接口方法需要由具體的子類容器實現。

ApplicationContext

ApplicationContext 這個類就再熟悉不過了,它是 Spring 框架中的核心容器。

如下圖所示,ApplicationContext 接口繼承了 ApplicationEventPublisher 接口,所以常用的 ApplicationContext 就可以用來發布事件。

以上介紹的 Spring 事件監聽發布角色串起來就是,通過 ApplicationEventPublisher 或者 ApplicationContext 容器發布  ApplicationEvent 事件并關聯事件對象,然后 ApplicationListener 監聽該事件,當事件發布后,監聽器就會收執行并獲取到事件及關聯對象。

Spring Boot 觀察者模式實戰

搞懂了 Spring 框架中的事件和監聽機制,那我們還是以上篇中觀察者模式的例子來改造下。

Spring Boot 基礎性的知識和搭建過程就不介紹了,不熟悉的可以關注公眾號Java技術棧,在后臺回復關鍵字 "boot" 閱讀我之前寫的系列教程。

所有 Spring Boot 教程實戰源碼在下面個倉庫:

https://github.com/javastacks/spring-boot-best-practice

新增觀察者目標類 

  1. import lombok.Getter;  
  2. import org.springframework.context.ApplicationEvent;  
  3. /**  
  4.  * 觀察目標:棧長  
  5.  * 來源微信公眾號:Java技術棧  
  6.  */  
  7. @Getter  
  8. public class JavaStackEvent extends ApplicationEvent {  
  9.     /**  
  10.      * Create a new {@code ApplicationEvent}.  
  11.      * 
  12.      * @param source the object on which the event initially occurred or with  
  13.      *               which the event is associated (never {@code null})  
  14.      */  
  15.     public JavaStackEvent(Object source) {  
  16.         super(source);  
  17.     }  

實現 Spring 框架中的 ApplicationEvent 應用程序事件接口,相當于是一個觀察者目標。

新增觀察者類 

  1. import lombok.NonNull;  
  2. import lombok.RequiredArgsConstructor;  
  3. import org.springframework.context.ApplicationListener;  
  4. import org.springframework.scheduling.annotation.Async;  
  5. /**  
  6.  * 觀察者:讀者粉絲  
  7.  * 來源微信公眾號:Java技術棧  
  8.  */  
  9. @RequiredArgsConstructor  
  10. public class ReaderListener implements ApplicationListener<JavaStackEvent> {  
  11.     @NonNull  
  12.     private String name;  
  13.     private String article; 
  14.     @Async  
  15.     @Override  
  16.     public void onApplicationEvent(JavaStackEvent event) {  
  17.         // 更新文章 
  18.         updateArticle(event);  
  19.     }  
  20.     private void updateArticle(JavaStackEvent event) {  
  21.         this.article = (String) event.getSource();  
  22.         System.out.printf("我是讀者:%s,文章已更新為:%s\n", this.name, this.article);  
  23.     }  

實現 Spring 框架中的 ApplicationListener 應用監聽接口,相當于是觀察者。

觀察目標和觀察者類結構圖如下:

新增測試配置類 

  1. import lombok.extern.slf4j.Slf4j;  
  2. import org.springframework.boot.CommandLineRunner;  
  3. import org.springframework.context.ApplicationContext;  
  4. import org.springframework.context.annotation.Bean; 
  5. import org.springframework.context.annotation.Configuration;  
  6. @Slf4j  
  7. @Configuration  
  8. public class ObserverConfiguration {  
  9.     @Bean  
  10.     public CommandLineRunner commandLineRunner(ApplicationContext context) {  
  11.         return (args) -> {  
  12.             log.info("發布事件:什么是觀察者模式?");  
  13.             context.publishEvent(new JavaStackEvent("什么是觀察者模式?"));  
  14.         };  
  15.     }  
  16.     @Bean  
  17.     public ReaderListener readerListener1(){  
  18.         return new ReaderListener("小明"); 
  19.     }  
  20.     @Bean  
  21.     public ReaderListener readerListener2(){  
  22.         return new ReaderListener("小張");  
  23.     }  
  24.     @Bean  
  25.     public ReaderListener readerListener3(){  
  26.         return new ReaderListener("小愛"); 
  27.     } 

在 Spring 配置中創建了三個讀者 Bean,在 Spring Boot 啟動后發布一個觀察者模式事件,然后這三個 Bean 就會收到通知。

輸出結果:

這里每個讀者創建一個 Bean 可能不太合適,因為要模仿上一個觀察者模式的應用。

實際中的觀察者模式應用應該是指具體業務,舉例說一個電商支付場景,在用戶支付完后可以發布一個支付事件,然后會有扣減積分,短信通知、贈送優惠券等一系列后續的事件監聽器觀察者,這樣可以實現業務解耦,這是一種很典型的應用場景。

如果大家有用到消息中間件,其實也是觀察者模式中發布訂閱模式的概念。

總結

利用 Spring 中的事件監聽機制也可以輕松實現觀察者模式,觀察目標也不需要維護觀察者列表了,相當于發布-訂閱模式,它們之間是完全解耦的,但每個觀察者需要創建一個 Bean。

好了,今天的分享就到這里了,又學了一種設計模式的寫法吧,后面棧長我會更新其他設計模式的實戰文章,公眾號Java技術棧第一時間推送。

本節教程所有實戰源碼已上傳到這個倉庫:

https://github.com/javastacks/spring-boot-best-practice 

 

責任編輯:龐桂玉 來源: Java編程
相關推薦

2021-03-29 07:14:28

Spring觀察者模式

2020-10-26 08:45:39

觀察者模式

2021-09-06 10:04:47

觀察者模式應用

2022-01-29 22:12:35

前端模式觀察者

2013-11-26 17:09:57

Android設計模式

2021-07-08 11:28:43

觀察者模式設計

2011-04-29 09:22:22

2024-12-03 09:34:35

觀察者模 式編程Javav

2012-08-27 10:52:20

.NET架構觀察者模式

2022-07-13 08:36:57

MQ架構設計模式

2024-02-18 12:36:09

2015-11-25 11:10:45

Javascript設計觀察

2009-03-30 09:39:04

觀察者思想換位設計模式

2024-06-04 13:11:52

Python行為設計模式開發

2021-01-25 05:38:04

設計原理VueSubject

2022-11-15 07:35:50

Spring事件觀察者模式

2021-09-29 19:45:24

觀察者模式Observable

2021-06-03 12:26:28

觀察者模式面試阿里P6

2020-12-09 05:18:17

面試觀察者訂閱模式

2022-05-09 10:50:13

觀察者模式設計模式
點贊
收藏

51CTO技術棧公眾號

主站蜘蛛池模板: 国产精品乱码一区二区三区 | 午夜精品一区二区三区在线播放 | 国产一级一片免费播放 | 91免费在线视频 | 免费一看一级毛片 | 亚洲精品一区国产精品 | 久久久久久免费精品一区二区三区 | 91视频在线 | 区一区二在线观看 | 国产精品美女久久久免费 | 自拍偷拍中文字幕 | 成人三级视频 | 欧美欧美欧美 | 欧美综合国产精品久久丁香 | 国产探花在线观看视频 | 日韩电影免费观看中文字幕 | 国产精品久久亚洲 | 亚洲www.| h在线 | 亚洲欧美日韩国产 | 91亚洲国产精品 | 欧美精品首页 | а天堂中文最新一区二区三区 | 三级黄色片在线 | 日韩欧美大片在线观看 | 国内精品久久久久久久影视简单 | 精品久久久一区 | 国产一区| 国产精品久久久久久久久免费丝袜 | 欧美视频福利 | 成人精品毛片国产亚洲av十九禁 | 亚洲精品视 | 亚洲中午字幕 | 荷兰欧美一级毛片 | 精品国产欧美一区二区三区成人 | 日韩中文久久 | 男人天堂色| 久操福利| 国产一区二区在线91 | 欧美一级二级视频 | 玖玖国产精品视频 |