最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

Java設(shè)計(jì)模式之java觀察者模式詳解

 更新時(shí)間:2021年09月15日 11:39:13   作者:大忽悠愛(ài)忽悠  
這篇文章主要介紹了Java經(jīng)典設(shè)計(jì)模式之觀察者模式,簡(jiǎn)單分析了觀察者模式的概念、原理并結(jié)合實(shí)例形式給出了java觀察者模式的具體用法與相關(guān)注意事項(xiàng),需要的朋友可以參考下

引言

觀察者模式是設(shè)計(jì)模式中的 “超級(jí)模式”,其應(yīng)用隨處可見(jiàn),我們以微信公眾號(hào)為例。

微信公眾號(hào)有服務(wù)號(hào)、訂閱號(hào)和企業(yè)號(hào)之分。當(dāng)我們?cè)诠娞?hào)上發(fā)布一篇博文推送時(shí),訂閱的用戶都能夠在我發(fā)布推送之后及時(shí)接收到推送,即可方便地在手機(jī)端進(jìn)行閱讀。

在這里插入圖片描述

介紹

觀察者模式(Observer Pattern):定義對(duì)象之間的一種一對(duì)多依賴(lài)關(guān)系,使得每當(dāng)一個(gè)對(duì)象狀態(tài)發(fā)生改變時(shí),其相關(guān)依賴(lài)對(duì)象皆得到通知并被自動(dòng)更新。觀察者模式是一種對(duì)象行為型模式。

觀察者模式的別名包括發(fā)布-訂閱(Publish/Subscribe)模式、模型-視圖(Model/View)模式、源-監(jiān)聽(tīng)器(Source/Listener)模式或從屬者(Dependents)模式。

觀察者模式包含觀察目標(biāo)和觀察者兩類(lèi)對(duì)象,**一個(gè)目標(biāo)可以有任意數(shù)目的與之相依賴(lài)的觀察者,**一旦觀察目標(biāo)的狀態(tài)發(fā)生改變,所有的觀察者都將得到通知。

  • 一般是多對(duì)一依賴(lài),即一個(gè)被觀察者,和多個(gè)觀察者
  • 一旦大忽悠更新了公眾號(hào),所有訂閱其公眾號(hào)的粉絲都會(huì)接收到更新推送

角色

Subject(目標(biāo)):目標(biāo)又稱(chēng)為主題,它是指被觀察的對(duì)象。在目標(biāo)中定義了一個(gè)觀察者集合,一個(gè)觀察目標(biāo)可以接受任意數(shù)量的觀察者來(lái)觀察,它提供一系列方法來(lái)增加和刪除觀察者對(duì)象,同時(shí)它定義了通知方法notify()。目標(biāo)類(lèi)可以是接口,也可以是抽象類(lèi)或具體類(lèi)。

ConcreteSubject(具體目標(biāo)):具體目標(biāo)是目標(biāo)類(lèi)的子類(lèi),通常它包含有經(jīng)常發(fā)生改變的數(shù)據(jù),當(dāng)它的狀態(tài)發(fā)生改變時(shí),向它的各個(gè)觀察者發(fā)出通知;同時(shí)它還實(shí)現(xiàn)了在目標(biāo)類(lèi)中定義的抽象業(yè)務(wù)邏輯方法(如果有的話)。如果無(wú)須擴(kuò)展目標(biāo)類(lèi),則具體目標(biāo)類(lèi)可以省略。

Observer(觀察者):觀察者將對(duì)觀察目標(biāo)的改變做出反應(yīng),觀察者一般定義為接口,該接口聲明了更新數(shù)據(jù)的方法update(),因此又稱(chēng)為抽象觀察者。

ConcreteObserver(具體觀察者):在具體觀察者中維護(hù)一個(gè)指向具體目標(biāo)對(duì)象的引用,它存儲(chǔ)具體觀察者的有關(guān)狀態(tài),這些狀態(tài)需要和具體目標(biāo)的狀態(tài)保持一致;它實(shí)現(xiàn)了在抽象觀察者Observer中定義的update()方法。通常在實(shí)現(xiàn)時(shí),可以調(diào)用具體目標(biāo)類(lèi)的attach()方法將自己添加到目標(biāo)類(lèi)的集合中或通過(guò)detach()方法將自己從目標(biāo)類(lèi)的集合中刪除。

原理類(lèi)圖

在這里插入圖片描述

微信訂閱號(hào)的案例

首先需要一個(gè)訂閱者接口(觀察者),該接口有一個(gè) receive 方法,用于接收公眾號(hào)推送通知

//訂閱者---觀察者
public interface Subscriber
{
    //接收發(fā)布者發(fā)布消息的方法
    public void receive();
}

然后是一個(gè)微信客戶端(具體觀察者),實(shí)現(xiàn)了 receive 方法

//處理微信訂閱的業(yè)務(wù)邏輯
public class WeChatSub implements Subscriber
{
    //當(dāng)前訂閱者的名字
    private String subName;
    WeChatSub(String subName)
    {
        this.subName=subName;
    }
    @Override
    public void receive(String publisher, String passageName) {
       //接收到推送消息時(shí)的具體業(yè)務(wù)邏輯操作
        System.out.println(String.format("用戶[%s] ,  接收到[%s]的訂閱號(hào)推送," +
                "推送文章為:%s ",subName,publisher,passageName));
    }
}

發(fā)布者類(lèi)(目標(biāo),被觀察對(duì)象),該類(lèi)維護(hù)了一個(gè)訂閱者列表,實(shí)現(xiàn)了訂閱、取消訂閱、通知所有訂閱者等功能

//發(fā)布者--被觀察的對(duì)象Subject
public class Publisher
{
    //存放所有需要通知的觀察者
   static private List<Subscriber> subscribers=new ArrayList<>();
   //記錄是否發(fā)布的狀態(tài),默認(rèn)false
    static private  Boolean pubStatus=false;
    protected void subscribe(Subscriber subscriber) {
        this.subscribers.add(subscriber);
    }
    protected void unsubscribe(Subscriber subscriber) {
        if (this.subscribers.contains(subscriber)) {
            this.subscribers.remove(subscriber);
        }
    }
    protected void notifySubscribers(String publisher, String articleName) {
        if (this.pubStatus == false) {
            return;
        }
        for (Subscriber subscriber : this.subscribers) {
            subscriber.receive(publisher, articleName);
        }
        this.clearPubStatus();
    }
    protected void setPubStatus() {
        this.pubStatus = true;
    }
    protected void clearPubStatus() {
        this.pubStatus = false;
    }
}

微信公眾號(hào)類(lèi)(具體目標(biāo)),該類(lèi)提供了 publishArticles 方法,用于發(fā)布推送,當(dāng)文章發(fā)布完畢時(shí)調(diào)用父類(lèi)的通知所有訂閱者方法

public class WeChatPublisher extends  Publisher
{
    private String name;
    public WeChatPublisher(String name) {
        this.name = name;
    }
    public void publishArticles(String articleName, String content) {
        System.out.println(String.format("\n<%s>微信公眾號(hào) 發(fā)布了一篇推送,文章名稱(chēng)為 <%s>,內(nèi)容為 <%s> ", this.name, articleName, content));
        setPubStatus();
        notifySubscribers(this.name, articleName);
    }
}

客戶端測(cè)試

//客戶端
public class Client
{
    public static void main(String[] args) {
        //創(chuàng)建一個(gè)發(fā)布者
        WeChatPublisher dhy=new WeChatPublisher("大忽悠");
        //創(chuàng)建訂閱者
        Subscriber sub1=new WeChatSub("小朋友");
        Subscriber sub2=new WeChatSub("小忽悠");
        Subscriber sub3=new WeChatSub("大朋友");
        //訂閱大忽悠公眾號(hào)
        dhy.subscribe(sub1);
        dhy.subscribe(sub2);
        dhy.subscribe(sub3);
        //大忽悠發(fā)布推送
        dhy.publishArticles("設(shè)計(jì)模式","觀察者模式");
    }
}

在這里插入圖片描述

總結(jié)

優(yōu)點(diǎn)

  • 觀察者模式可以實(shí)現(xiàn)表示層和數(shù)據(jù)邏輯層的分離,定義了穩(wěn)定的消息更新傳遞機(jī)制,并抽象了更新接口,使得可以有各種各樣不同的表示層充當(dāng)具體觀察者角色。
  • 觀察者模式在觀察目標(biāo)和觀察者之間建立一個(gè)抽象的耦合。觀察目標(biāo)只需要維持一個(gè)抽象觀察者的集合,無(wú)須了解其具體觀察者。由于觀察目標(biāo)和觀察者沒(méi)有緊密地耦合在一起,因此它們可以屬于不同的抽象化層次。
  • 觀察者模式支持廣播通信,觀察目標(biāo)會(huì)向所有已注冊(cè)的觀察者對(duì)象發(fā)送通知,簡(jiǎn)化了一對(duì)多系統(tǒng)設(shè)計(jì)的難度。
  • 觀察者模式滿足 “開(kāi)閉原則”的要求,增加新的具體觀察者無(wú)須修改原有系統(tǒng)代碼,在具體觀察者與觀察目標(biāo)之間不存在關(guān)聯(lián)關(guān)系的情況下,增加新的觀察目標(biāo)也很方便。

缺點(diǎn)

  • 如果一個(gè)觀察目標(biāo)對(duì)象有很多直接和間接觀察者,將所有的觀察者都通知到會(huì)花費(fèi)很多時(shí)間。
  • 如果在觀察者和觀察目標(biāo)之間存在循環(huán)依賴(lài),觀察目標(biāo)會(huì)觸發(fā)它們之間進(jìn)行循環(huán)調(diào)用,可能導(dǎo)致系統(tǒng)崩潰。
  • 觀察者模式?jīng)]有相應(yīng)的機(jī)制讓觀察者知道所觀察的目標(biāo)對(duì)象是怎么發(fā)生變化的,而僅僅只是知道觀察目標(biāo)發(fā)生了變化。

適用場(chǎng)景

  • 一個(gè)抽象模型有兩個(gè)方面,其中一個(gè)方面依賴(lài)于另一個(gè)方面,將這兩個(gè)方面封裝在獨(dú)立的對(duì)象中使它們可以各自獨(dú)立地改變和復(fù)用。
  • 一個(gè)對(duì)象的改變將導(dǎo)致一個(gè)或多個(gè)其他對(duì)象也發(fā)生改變,而并不知道具體有多少對(duì)象將發(fā)生改變,也不知道這些對(duì)象是誰(shuí)。
  • 需要在系統(tǒng)中創(chuàng)建一個(gè)觸發(fā)鏈,A對(duì)象的行為將影響B(tài)對(duì)象,B對(duì)象的行為將影響C對(duì)象……,可以使用觀察者模式創(chuàng)建一種鏈?zhǔn)接|發(fā)機(jī)制。

觀察者模式的典型應(yīng)用

JDK 提供的觀察者接口

觀察者模式在Java語(yǔ)言中的地位非常重要。在JDK的 java.util 包中,提供了 Observable 類(lèi)以及 Observer 接口,它們構(gòu)成了JDK對(duì)觀察者模式的支持。

其中的 Observer 接口為觀察者,只有一個(gè) update 方法,當(dāng)觀察目標(biāo)發(fā)生變化時(shí)被調(diào)用,其代碼如下:

public interface Observer {
    void update(Observable o, Object arg);
}

Observable 類(lèi)則為目標(biāo)類(lèi),相比我們的示例中的 Publisher 類(lèi)多了并發(fā)和NPE方面的考慮

public class Observable {
    private boolean changed = false;
    private Vector<Observer> obs = new Vector();
    public Observable() {
    }
    // 用于注冊(cè)新的觀察者對(duì)象到向量中
    public synchronized void addObserver(Observer var1) {
        if (var1 == null) {
            throw new NullPointerException();
        } else {
            if (!this.obs.contains(var1)) {
                this.obs.addElement(var1);
            }
        }
    }
    // 用于刪除向量中的某一個(gè)觀察者對(duì)象
    public synchronized void deleteObserver(Observer var1) {
        this.obs.removeElement(var1);
    }
    public void notifyObservers() {
        this.notifyObservers((Object)null);
    }
    // 通知方法,用于在方法內(nèi)部循環(huán)調(diào)用向量中每一個(gè)觀察者的update()方法
    public void notifyObservers(Object var1) {
        Object[] var2;
        synchronized(this) {
            if (!this.changed) {
                return;
            }
            var2 = this.obs.toArray();
            this.clearChanged();
        }
        for(int var3 = var2.length - 1; var3 >= 0; --var3) {
            ((Observer)var2[var3]).update(this, var1);
        }
    }
    // 用于清空向量,即刪除向量中所有觀察者對(duì)象
    public synchronized void deleteObservers() {
        this.obs.removeAllElements();
    }
    // 該方法被調(diào)用后會(huì)設(shè)置一個(gè)boolean類(lèi)型的內(nèi)部標(biāo)記變量changed的值為true,表示觀察目標(biāo)對(duì)象的狀態(tài)發(fā)生了變化
    protected synchronized void setChanged() {
        this.changed = true;
    }
    // 用于將changed變量的值設(shè)為false,表示對(duì)象狀態(tài)不再發(fā)生改變或者已經(jīng)通知了所有的觀察者對(duì)象,調(diào)用了它們的update()方法
    protected synchronized void clearChanged() {
        this.changed = false;
    }
    // 返回對(duì)象狀態(tài)是否改變
    public synchronized boolean hasChanged() {
        return this.changed;
    }
    // 返回向量中觀察者的數(shù)量
    public synchronized int countObservers() {
        return this.obs.size();
    }
}

我們可以使用 Observable 類(lèi)以及 Observer 接口來(lái)重新實(shí)現(xiàn)微信公眾號(hào)示例。

增加一個(gè)通知類(lèi) WechatNotice,用于推送通知的傳遞

@Data
@AllArgsConstructor
public class WechatNotice {
    private String publisher;
    private String articleName;
}

然后改寫(xiě) WeChatClient WeChatAccounts,分別實(shí)現(xiàn)JDK的 Observer 接口和繼承 Observable 類(lèi)

public class WeChatClient implements Observer {
    private String username;
    public WeChatClient(String username) {
        this.username = username;
    }
    @Override
    public void update(Observable o, Object arg) {
        //WeChatAccounts weChatAccounts = (WeChatAccounts) o;
        WechatNotice notice = (WechatNotice) arg;
        System.out.println(String.format("用戶<%s> 接收到 <%s>微信公眾號(hào) 的推送,文章標(biāo)題為 <%s>", username, notice.getPublisher(), notice.getArticleName()));
    }
}
public class WeChatAccounts extends Observable {
    private String name;
    public WeChatAccounts(String name) {
        this.name = name;
    }
    public void publishArticles(String articleName, String content) {
        System.out.println(String.format("\n<%s>微信公眾號(hào) 發(fā)布了一篇推送,文章名稱(chēng)為 <%s>,內(nèi)容為 <%s> ", this.name, articleName, content));
        setChanged();
        notifyObservers(new WechatNotice(this.name, articleName));
    }
}

測(cè)試,與示例中的測(cè)試代碼的區(qū)別在于調(diào)用的方法不同

public class Test {
    public static void main(String[] args) {
        WeChatAccounts accounts = new WeChatAccounts("大忽悠");
        WeChatClient user1 = new WeChatClient("張三");
        WeChatClient user2 = new WeChatClient("李四");
        WeChatClient user3 = new WeChatClient("王五");
        accounts.addObserver(user1);
        accounts.addObserver(user2);
        accounts.addObserver(user3);
        accounts.publishArticles("設(shè)計(jì)模式 | 觀察者模式及典型應(yīng)用", "觀察者模式的內(nèi)容...");
        accounts.deleteObserver(user1);
        accounts.publishArticles("設(shè)計(jì)模式 | 單例模式及典型應(yīng)用", "單例模式的內(nèi)容....");
    }
}

Guava EventBus 中的觀察者模式

Guava 中的 EventBus 封裝了友好的 “生產(chǎn)/消費(fèi)模型”,通過(guò)非常簡(jiǎn)單的方式,實(shí)現(xiàn)了觀察者模式中的監(jiān)聽(tīng)注冊(cè),事件分發(fā)。

使用了 Guava EventBus 之后,如果需要訂閱消息,不需要實(shí)現(xiàn)任何接口,只需在監(jiān)聽(tīng)方法上加上 @Subscribe 注解即可,EventBus 提供了 registerunregister 方法用于注冊(cè)與取消注冊(cè)事件,當(dāng) EventBus 調(diào)用 post 方法時(shí)將把事件分發(fā)給注冊(cè)的對(duì)象

使用 Guava 重新實(shí)現(xiàn)示例

@Data
@AllArgsConstructor
public class WechatNotice {
    private String publisher;
    private String articleName;
}
public class WeChatClient  {
    private String username;
    public WeChatClient(String username) {
        this.username = username;
    }
    @Subscribe
    public void listen(WechatNotice notice) {
        System.out.println(String.format("用戶<%s> 接收到 <%s>微信公眾號(hào) 的推送,文章標(biāo)題為 <%s>", username, notice.getPublisher(), notice.getArticleName()));
    }
}
public class WeChatAccounts {
    private String name;
    private EventBus eventBus;
    public WeChatAccounts(String name) {
        this.name = name;
        this.eventBus = new EventBus();
    }
    public void publishArticles(String articleName, String content) {
        System.out.println(String.format("\n<%s>微信公眾號(hào) 發(fā)布了一篇推送,文章名稱(chēng)為 <%s>,內(nèi)容為 <%s> ", this.name, articleName, content));
        //post方法將會(huì)將被派發(fā)的消息,傳遞給所有的訂閱者,并調(diào)用訂閱者的監(jiān)聽(tīng)方法
        this.eventBus.post(new WechatNotice(this.name, articleName));
    }
    public void register(WeChatClient weChatClient) {
        this.eventBus.register(weChatClient);
    }
    public void unregister(WeChatClient weChatClient) {
        this.eventBus.unregister(weChatClient);
    }
}

測(cè)試

public class Test {
    public static void main(String[] args) {
        WeChatAccounts accounts = new WeChatAccounts("小旋鋒");
        WeChatClient user1 = new WeChatClient("張三");
        WeChatClient user2 = new WeChatClient("李四");
        WeChatClient user3 = new WeChatClient("王五");
        accounts.register(user1);
        accounts.register(user2);
        accounts.register(user3);
        accounts.publishArticles("設(shè)計(jì)模式 | 觀察者模式及典型應(yīng)用", "觀察者模式的內(nèi)容...");
        accounts.unregister(user1);
        accounts.publishArticles("設(shè)計(jì)模式 | 單例模式及典型應(yīng)用", "單例模式的內(nèi)容....");
    }
}

Spring ApplicationContext 事件機(jī)制中的觀察者模式

spring的事件機(jī)制是從java的事件機(jī)制拓展而來(lái),ApplicationContext 中事件處理是由 ApplicationEvent 類(lèi)和 ApplicationListener 接口來(lái)提供的。如果一個(gè)Bean實(shí)現(xiàn)了 ApplicationListener 接口,并且已經(jīng)發(fā)布到容器中去,每次 ApplicationContext 發(fā)布一個(gè) ApplicationEvent 事件,這個(gè)Bean就會(huì)接到通知

  • ApplicationContext:事件源,其中的 publishEvent()方法用于觸發(fā)容器事件
  • ApplicationEvent:事件本身,自定義事件需要繼承該類(lèi),可以用來(lái)傳遞數(shù)據(jù)
  • ApplicationListener:事件監(jiān)聽(tīng)器接口,事件的業(yè)務(wù)邏輯封裝在監(jiān)聽(tīng)器里面
@Data
public class WechatNotice extends ApplicationEvent {
    private String publisher;
    private String articleName;
    public WechatNotice(Object source, String publisher, String articleName) {
        super(source);
        this.publisher = publisher;
        this.articleName = articleName;
    }
}
public class WeChatClient implements ApplicationListener {
    private String username;
    public WeChatClient(String username) {
        this.username = username;
    }
    @Override
    public void onApplicationEvent(ApplicationEvent event) {
        if (event instanceof WechatNotice) {
            WechatNotice notice = (WechatNotice) event;
            System.out.println(String.format("用戶<%s> 接收到 <%s>微信公眾號(hào) 的推送,文章標(biāo)題為 <%s>", username, notice.getPublisher(), notice.getArticleName()));
        }
    }
    public void setUsername(String username) {
        this.username = username;
    }
}

public class WeChatAccounts implements ApplicationContextAware {
    private ApplicationContext ctx;
    private String name;
    public WeChatAccounts(String name) {
        this.name = name;
    }
    public void setName(String name) {
        this.name = name;
    }
    @Override
    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
        this.ctx = applicationContext;
    }
    public void publishArticles(String articleName, String content) {
        System.out.println(String.format("\n<%s>微信公眾號(hào) 發(fā)布了一篇推送,文章名稱(chēng)為 <%s>,內(nèi)容為 <%s> ", this.name, articleName, content));
        ctx.publishEvent(new WechatNotice(this.name, this.name, articleName));
    }
}

在 resources 目錄下創(chuàng)建 spring.xml 文件,填入下面的內(nèi)容

<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
    <bean id="WeChatAccounts" class="com.observer.sprintevent.WeChatAccounts" scope="prototype">
        <constructor-arg name="name" value=""></constructor-arg>
    </bean>
    <bean id="WeChatClient1" class="com.observer.sprintevent.WeChatClient">
        <constructor-arg name="username" value="張三"></constructor-arg>
    </bean>
    <bean id="WeChatClient2" class="com.observer.sprintevent.WeChatClient">
        <constructor-arg name="username" value="李四"></constructor-arg>
    </bean>
    <bean id="WeChatClient3" class="com.observer.sprintevent.WeChatClient">
        <constructor-arg name="username" value="王五"></constructor-arg>
    </bean>
</beans>

測(cè)試

public class Test {
    public static void main(String[] args) {
        ApplicationContext context = new ClassPathXmlApplicationContext("spring.xml");
        WeChatAccounts accounts = (WeChatAccounts) context.getBean("WeChatAccounts");
        accounts.setName("大忽悠");
        accounts.setApplicationContext(context);
        accounts.publishArticles("設(shè)計(jì)模式 | 觀察者模式及典型應(yīng)用", "觀察者模式的內(nèi)容...");
    }
}

在此示例中 ApplicationContext 對(duì)象的實(shí)際類(lèi)型為 ClassPathXmlApplicationContext,其中的與 publishEvent 方法相關(guān)的主要代碼如下:

private ApplicationEventMulticaster applicationEventMulticaster;
public void publishEvent(ApplicationEvent event) {
    this.getApplicationEventMulticaster().multicastEvent(event);
    if (this.parent != null) {
        this.parent.publishEvent(event);
    }
}
ApplicationEventMulticaster getApplicationEventMulticaster() throws IllegalStateException {
    return this.applicationEventMulticaster;
}
protected void initApplicationEventMulticaster() {
        ConfigurableListableBeanFactory beanFactory = this.getBeanFactory();
        if (beanFactory.containsLocalBean("applicationEventMulticaster")) {
            this.applicationEventMulticaster = (ApplicationEventMulticaster)beanFactory.getBean("applicationEventMulticaster", ApplicationEventMulticaster.class);
        } else {
            this.applicationEventMulticaster = new SimpleApplicationEventMulticaster(beanFactory);
            beanFactory.registerSingleton("applicationEventMulticaster", this.applicationEventMulticaster);
        }
    }

其中的 SimpleApplicationEventMulticaster 如下,multicastEvent 方法主要是通過(guò)遍歷 ApplicationListener(注冊(cè)由 AbstractApplicationEventMulticaster 實(shí)現(xiàn)),使用線程池框架 Executor 來(lái)并發(fā)執(zhí)行 ApplicationListener 的 onApplicationEvent 方法,與示例本質(zhì)上是一致的

public class SimpleApplicationEventMulticaster extends AbstractApplicationEventMulticaster {
    private Executor taskExecutor;
    public void multicastEvent(final ApplicationEvent event) {
        Iterator var2 = this.getApplicationListeners(event).iterator();
        while(var2.hasNext()) {
            final ApplicationListener listener = (ApplicationListener)var2.next();
            Executor executor = this.getTaskExecutor();
            if (executor != null) {
                executor.execute(new Runnable() {
                    public void run() {
                        listener.onApplicationEvent(event);
                    }
                });
            } else {
                listener.onApplicationEvent(event);
            }
        }
    }
}

參考文章

springboot啟動(dòng)源碼

設(shè)計(jì)模式 | 觀察者模式及典型應(yīng)用

總結(jié)

本篇文章就到這里了,希望能夠給你帶來(lái)幫助,也希望您能夠多多關(guān)注腳本之家的更多內(nèi)容!

相關(guān)文章

  • Java 實(shí)現(xiàn)棧的三種方式

    Java 實(shí)現(xiàn)棧的三種方式

    這篇文章主要介紹了棧:LIFO(后進(jìn)先出),自己實(shí)現(xiàn)一個(gè)棧,要求這個(gè)棧具有push()、pop()(返回棧頂元素并出棧)、peek() (返回棧頂元素不出棧)、isEmpty()這些基本的方法,需要的朋友可以參考下
    2020-12-12
  • Spring使用注解方式實(shí)現(xiàn)創(chuàng)建對(duì)象

    Spring使用注解方式實(shí)現(xiàn)創(chuàng)建對(duì)象

    這篇文章主要介紹了Spring使用注解方式實(shí)現(xiàn)創(chuàng)建對(duì)象,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2023-02-02
  • 一文帶你搞懂Java中線程的創(chuàng)建方式

    一文帶你搞懂Java中線程的創(chuàng)建方式

    這篇文章主要為大家詳細(xì)介紹了Java中線程的創(chuàng)建方式的相關(guān)知識(shí),文中的示例代碼講解詳細(xì),具有一定的借鑒價(jià)值,感興趣的小伙伴可以了解一下
    2023-03-03
  • 如何解決maven搭建一直處于running:..狀態(tài)問(wèn)題

    如何解決maven搭建一直處于running:..狀態(tài)問(wèn)題

    在使用Maven搭建項(xiàng)目時(shí),有時(shí)會(huì)遇到一直處于加載狀態(tài)的情況,通過(guò)修改設(shè)置可以解決這個(gè)問(wèn)題,具體步驟為:1. 打開(kāi)File->Settings->Build, Execution, Deployment->Maven->running,然后在VMOptions中填寫(xiě)"-DarchetypeCatalog=internal"
    2024-09-09
  • SpringBoot大事務(wù)問(wèn)題的常用優(yōu)化方案

    SpringBoot大事務(wù)問(wèn)題的常用優(yōu)化方案

    大事務(wù)是指運(yùn)行時(shí)間比較長(zhǎng),操作的數(shù)據(jù)比較多的事務(wù)123,大事務(wù)的產(chǎn)生原因包括操作的數(shù)據(jù)比較多、大量的鎖競(jìng)爭(zhēng)、事務(wù)中有其他非數(shù)據(jù)庫(kù)的耗時(shí)操作等,本文給大家總結(jié)了SpringBoot大事務(wù)問(wèn)題的常用優(yōu)化方案,需要的朋友可以參考下
    2024-04-04
  • 聊聊Spring AOP @Before @Around @After等advice的執(zhí)行順序

    聊聊Spring AOP @Before @Around @After等advice的執(zhí)行順序

    這篇文章主要介紹了聊聊Spring AOP @Before @Around @After等advice的執(zhí)行順序,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧
    2021-02-02
  • SpringBoot中@EnableAutoConfiguration注解源碼分析

    SpringBoot中@EnableAutoConfiguration注解源碼分析

    這篇文章主要介紹了SpringBoot中@EnableAutoConfiguration注解源碼分析,@EnableAutoConfiguration,主要是用于加載Starter目錄包之外的、需要Spring自動(dòng)生成Bean對(duì)象的、帶有@Configuration注解的類(lèi),需要的朋友可以參考下
    2023-08-08
  • java日志LoggerFactory.getLogger的用法及說(shuō)明

    java日志LoggerFactory.getLogger的用法及說(shuō)明

    這篇文章主要介紹了java日志LoggerFactory.getLogger的用法及說(shuō)明,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2023-02-02
  • RestTemplate使用不當(dāng)引發(fā)的問(wèn)題及解決

    RestTemplate使用不當(dāng)引發(fā)的問(wèn)題及解決

    這篇文章主要介紹了RestTemplate使用不當(dāng)引發(fā)的問(wèn)題及解決,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2021-10-10
  • Java ArrayList的不同排序方法

    Java ArrayList的不同排序方法

    這篇文章主要介紹了Java ArrayList的不同排序方法,感興趣的小伙伴們可以參考一下
    2015-12-12

最新評(píng)論

天门市| 竹北市| 梅河口市| 报价| 陈巴尔虎旗| 黎平县| 通化县| 绥芬河市| 太湖县| 吉林省| 天气| 措美县| 保德县| 榆林市| 玉门市| 望谟县| 宜章县| 崇礼县| 即墨市| 政和县| 浪卡子县| 剑河县| 博白县| 华安县| 双峰县| 大方县| 斗六市| 盖州市| 太康县| 清远市| 甘洛县| 铅山县| 万州区| 邢台市| 青海省| 平陆县| 岚皋县| 拜城县| 安乡县| 张家港市| 信宜市|