溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊(cè)×
其他方式登錄
點(diǎn)擊 登錄注冊(cè) 即表示同意《億速云用戶服務(wù)條款》

基于Spring實(shí)現(xiàn)觀察者模式的方法步驟

發(fā)布時(shí)間:2021-10-09 15:59:46 來(lái)源:億速云 閱讀:109 作者:iii 欄目:編程語(yǔ)言

這篇文章主要介紹“基于Spring實(shí)現(xiàn)觀察者模式的方法步驟”,在日常操作中,相信很多人在基于Spring實(shí)現(xiàn)觀察者模式的方法步驟問(wèn)題上存在疑惑,小編查閱了各式資料,整理出簡(jiǎn)單好用的操作方法,希望對(duì)大家解答”基于Spring實(shí)現(xiàn)觀察者模式的方法步驟”的疑惑有所幫助!接下來(lái),請(qǐng)跟著小編一起來(lái)學(xué)習(xí)吧!

觀察者模式定義對(duì)象間的一種一對(duì)多的依賴關(guān)系,當(dāng)一個(gè)對(duì)象的狀態(tài)發(fā)生改變時(shí),所有依賴于它的對(duì)象都得到通知并被自動(dòng)更新,其主要解決一個(gè)對(duì)象狀態(tài)改變給其他關(guān)聯(lián)對(duì)象通知的問(wèn)題,保證易用和低耦合。一個(gè)典型的應(yīng)用場(chǎng)景是:當(dāng)用戶注冊(cè)以后,需要給用戶發(fā)送郵件,發(fā)送優(yōu)惠券等操作,如下圖所示。

UserService 在完成自身的用戶注冊(cè)邏輯之后,僅僅只需要發(fā)布一個(gè) UserRegisterEvent 事件,而無(wú)需關(guān)注其它拓展邏輯。其它 Service 可以自己訂閱 UserRegisterEvent 事件,實(shí)現(xiàn)自定義的拓展邏輯。Spring的事件機(jī)制主要由3個(gè)部分組成。

  • ApplicationEvent:通過(guò)繼承它,實(shí)現(xiàn)自定義事件。另外,通過(guò)它的 source 屬性可以獲取事件源,timestamp 屬性可以獲得發(fā)生時(shí)間。

  • ApplicationEventPublisher:通過(guò)實(shí)現(xiàn)它,來(lái)發(fā)布變更事件。

  • ApplicationEventListener:通過(guò)實(shí)現(xiàn)它,來(lái)監(jiān)聽(tīng)指定類型事件并響應(yīng)動(dòng)作。這里就以上面的用戶注冊(cè)為例,來(lái)看看代碼示例。首先定義用戶注冊(cè)事件 UserRegisterEvent。

publicclass UserRegisterEvent extends ApplicationEvent {
    /**
     * 用戶名
     */
    private String username;
    public UserRegisterEvent(Object source) {
        super(source);
    }
    public UserRegisterEvent(Object source, String username) {
        super(source);
        this.username = username;
    }
    public String getUsername() {
        return username;
    }
}

然后定義用戶注冊(cè)服務(wù)類,實(shí)現(xiàn) ApplicationEventPublisherAware 接口,從而將 ApplicationEventPublisher 注入進(jìn)來(lái)。從下面代碼可以看到,在執(zhí)行完注冊(cè)邏輯后,調(diào)用了 ApplicationEventPublisher的 publishEvent(ApplicationEvent event) 方法,發(fā)布了 UserRegisterEvent 事件。

@Service
publicclass UserService implements ApplicationEventPublisherAware { // <1>
    private Logger logger = LoggerFactory.getLogger(getClass());
    private ApplicationEventPublisher applicationEventPublisher;
    @Override
    public void setApplicationEventPublisher(ApplicationEventPublisher applicationEventPublisher) {
        this.applicationEventPublisher = applicationEventPublisher;
    }
    public void register(String username) {
        // ... 執(zhí)行注冊(cè)邏輯
        logger.info("[register][執(zhí)行用戶({}) 的注冊(cè)邏輯]", username);
        // <2> ... 發(fā)布
        applicationEventPublisher.publishEvent(new UserRegisterEvent(this, username));
    }
}

創(chuàng)建郵箱Service,實(shí)現(xiàn) ApplicationListener 接口,通過(guò) E 泛型設(shè)置感興趣的事件,實(shí)現(xiàn) onApplicationEvent(E event) 方法,針對(duì)監(jiān)聽(tīng)的 UserRegisterEvent 事件,進(jìn)行自定義處理。

@Service
publicclass EmailService implements ApplicationListener<UserRegisterEvent> { // <1>
    private Logger logger = LoggerFactory.getLogger(getClass());
    @Override
    @Async// <3>
    public void onApplicationEvent(UserRegisterEvent event) { // <2>
        logger.info("[onApplicationEvent][給用戶({}) 發(fā)送郵件]", event.getUsername());
    }
}

創(chuàng)建優(yōu)惠券Service,不同于上面的實(shí)現(xiàn) ApplicationListener 接口方式,在方法上,添加 @EventListener 注解,并設(shè)置監(jiān)聽(tīng)的事件為 UserRegisterEvent。這是另一種使用方式。

@Service
publicclass CouponService {
    private Logger logger = LoggerFactory.getLogger(getClass());
    @EventListener// <1>
    public void addCoupon(UserRegisterEvent event) {
        logger.info("[addCoupon][給用戶({}) 發(fā)放優(yōu)惠劵]", event.getUsername());
    }
}

看到這里,細(xì)心的同學(xué)可能想到了發(fā)布訂閱模式,其實(shí)觀察者模式于發(fā)布訂閱還是有區(qū)別的,簡(jiǎn)單來(lái)說(shuō),發(fā)布訂閱模式屬于廣義上的觀察者模式,在觀察者模式的 Subject 和 Observer 的基礎(chǔ)上,引入 Event Channel 這個(gè)中介,進(jìn)一步解耦。圖示如下,可以看出,觀察者模式更加輕量,通常用于單機(jī),而發(fā)布訂閱模式相對(duì)而言更重一些,通常用于分布式環(huán)境下的消息通知場(chǎng)景。

到此,關(guān)于“基于Spring實(shí)現(xiàn)觀察者模式的方法步驟”的學(xué)習(xí)就結(jié)束了,希望能夠解決大家的疑惑。理論與實(shí)踐的搭配能更好的幫助大家學(xué)習(xí),快去試試吧!若想繼續(xù)學(xué)習(xí)更多相關(guān)知識(shí),請(qǐng)繼續(xù)關(guān)注億速云網(wǎng)站,小編會(huì)繼續(xù)努力為大家?guī)?lái)更多實(shí)用的文章!

向AI問(wèn)一下細(xì)節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權(quán)請(qǐng)聯(lián)系站長(zhǎng)郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI