欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

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

 更新時(shí)間:2021年09月15日 11:09:21   作者:大忽悠愛(ài)忽悠  
這篇文章主要為大家詳細(xì)介紹了23種設(shè)計(jì)模式之java中介者模式,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下,希望能夠給你帶來(lái)幫助

引言

一般來(lái)說(shuō),同事類之間的關(guān)系是比較復(fù)雜的,多個(gè)同事類之間互相關(guān)聯(lián)時(shí),他們之間的關(guān)系會(huì)呈現(xiàn)為復(fù)雜的網(wǎng)狀結(jié)構(gòu),這是一種過(guò)度耦合的架構(gòu),即不利于類的復(fù)用,也不穩(wěn)定。例如在下圖中,有六個(gè)同事類對(duì)象,假如對(duì)象1發(fā)生變化,那么將會(huì)有4個(gè)對(duì)象受到影響。如果對(duì)象2發(fā)生變化,那么將會(huì)有5個(gè)對(duì)象受到影響。也就是說(shuō),同事類之間直接關(guān)聯(lián)的設(shè)計(jì)是不好的。

在這里插入圖片描述

如果引入中介者模式,那么同事類之間的關(guān)系將變?yōu)樾切徒Y(jié)構(gòu),從圖中可以看到,任何一個(gè)類的變動(dòng),只會(huì)影響的類本身,以及中介者,這樣就減小了系統(tǒng)的耦合。一個(gè)好的設(shè)計(jì),必定不會(huì)把所有的對(duì)象關(guān)系處理邏輯封裝在本類中,而是使用一個(gè)專門的類來(lái)管理那些不屬于自己的行為。

在這里插入圖片描述

介紹

中介者模式(Mediator Pattern):用一個(gè)中介對(duì)象(中介者)來(lái)封裝一系列的對(duì)象交互,中介者使各對(duì)象不需要顯式地相互引用,從而使其耦合松散,而且可以獨(dú)立地改變它們之間的交互。中介者模式又稱為調(diào)停者模式,它是一種對(duì)象行為型模式。

角色

  • Mediator(抽象中介者):它定義一個(gè)接口,該接口用于與各同事對(duì)象之間進(jìn)行通信。
  • ConcreteMediator(具體中介者):它是抽象中介者的子類,通過(guò)協(xié)調(diào)各個(gè)同事對(duì)象來(lái)實(shí)現(xiàn)協(xié)作行為,它維持了對(duì)各個(gè)同事對(duì)象的引用。
  • Colleague(抽象同事類):它定義各個(gè)同事類公有的方法,并聲明了一些抽象方法來(lái)供子類實(shí)現(xiàn),同時(shí)它維持了一個(gè)對(duì)抽象中介者類的引用,其子類可以通過(guò)該引用來(lái)與中介者通信。
  • ConcreteColleague(具體同事類):它是抽象同事類的子類;每一個(gè)同事對(duì)象在需要和其他同事對(duì)象通信時(shí),先與中介者通信,通過(guò)中介者來(lái)間接完成與其他同事類的通信;在具體同事類中實(shí)現(xiàn)了在抽象同事類中聲明的抽象方法。

中介者模式的核心在于中介者類的引入,在中介者模式中,中介者類承擔(dān)了兩方面的職責(zé):

  • 中轉(zhuǎn)作用(結(jié)構(gòu)性):通過(guò)中介者提供的中轉(zhuǎn)作用,各個(gè)同事對(duì)象就不再需要顯式引用其他同事,當(dāng)需要和其他同事進(jìn)行通信時(shí),可通過(guò)中介者來(lái)實(shí)現(xiàn)間接調(diào)用。該中轉(zhuǎn)作用屬于中介者在結(jié)構(gòu)上的支持。
  • 協(xié)調(diào)作用(行為性):中介者可以更進(jìn)一步的對(duì)同事之間的關(guān)系進(jìn)行封裝,同事可以一致的和中介者進(jìn)行交互,而不需要指明中介者需要具體怎么做,中介者根據(jù)封裝在自身內(nèi)部的協(xié)調(diào)邏輯,對(duì)同事的請(qǐng)求進(jìn)行進(jìn)一步處理,將同事成員之間的關(guān)系行為進(jìn)行分離和封裝。

開(kāi)發(fā)中常見(jiàn)的場(chǎng)景

  • MVC模式(Controller 是中介者,根據(jù) View 層的請(qǐng)求來(lái)操作 Model 層)
  • 窗口游戲程序,窗口軟件開(kāi)發(fā)中窗口對(duì)象也是一個(gè)中介者對(duì)象
  • 圖形界面開(kāi)發(fā)GUI中,多個(gè)組件之間的交互,可以通過(guò)引入一個(gè)中介者對(duì)象來(lái)解決,可以是整體的窗口對(duì)象或者DOM對(duì)象
  • Java.lang.reflect.Method#invoke()

數(shù)據(jù)庫(kù)同步數(shù)據(jù)案例

我們來(lái)實(shí)現(xiàn)一個(gè)簡(jiǎn)化版的數(shù)據(jù)同步方案,有三種數(shù)據(jù)庫(kù) Mysql、Redis、Elasticsearch

  • 其中的 Mysql 作為主數(shù)據(jù)庫(kù),當(dāng)增加一條數(shù)據(jù)時(shí)需要同步到另外兩個(gè)數(shù)據(jù)庫(kù)中;
  • Redis 作為緩存數(shù)據(jù)庫(kù),當(dāng)增加一條數(shù)據(jù)時(shí)不需要同步到另外另個(gè)數(shù)據(jù)庫(kù);
  • 而 Elasticsearch 作為大數(shù)據(jù)查詢數(shù)據(jù)庫(kù),有一個(gè)統(tǒng)計(jì)功能,當(dāng)增加一條數(shù)據(jù)時(shí)只需要同步到 Mysql,

所以它們之間的關(guān)系圖如下所示。

在這里插入圖片描述

不使用中介者模式的數(shù)據(jù)同步方案,各數(shù)據(jù)源維護(hù)各自的同步作業(yè)

抽象數(shù)據(jù)庫(kù)

public abstract class AbstractDatabase
{
    //存儲(chǔ)數(shù)據(jù)
    protected LinkedList<String> datas=new LinkedList<>();
    //向自己的數(shù)據(jù)庫(kù)中增加數(shù)據(jù)的方法
    public abstract void addData(String data);
    //同步數(shù)據(jù)的方法--默認(rèn)空實(shí)現(xiàn)
    public void DataStore(String data){}
    //展示當(dāng)前數(shù)據(jù)庫(kù)所有數(shù)據(jù)
    public void display()
    {
        datas.forEach(x->System.out.println(x));
    }
}

具體數(shù)據(jù)庫(kù) Mysql,維護(hù)同步到 Redis和Elasticsearch 的同步作業(yè)

public class MySql extends AbstractDatabase
{
    @Setter
     private Elasticsearch elasticsearch;
    @Setter
    private Redis redis;
     //向自己的數(shù)據(jù)庫(kù)增加數(shù)據(jù)
    @Override
    public void addData(String data)
    {
        System.out.println("====向Mysql數(shù)據(jù)庫(kù)增加一條數(shù)據(jù)====");
        System.out.println("增加的數(shù)據(jù)為:"+data);
        System.out.println("=====================================");
        datas.add(data);
    }
     //重寫父類數(shù)據(jù)同步的方法
    @Override
    public void DataStore(String data)
    {
        addData(data);
        elasticsearch.addData(data);
        redis.addData(data);
    }
}

Elasticsearch ,只需要同步到Mysql

public class Elasticsearch  extends AbstractDatabase
{
    @Setter
    private  MySql mySql;
    //給自己增加數(shù)據(jù)的方法
    @Override
    public void addData(String data)
    {
        System.out.println("====向Elasticsearch數(shù)據(jù)庫(kù)增加一條數(shù)據(jù)====");
        System.out.println("增加的數(shù)據(jù)為:"+data);
        System.out.println("=====================================");
        datas.add(data);
    }
    //重寫父類數(shù)據(jù)同步的方法
    @Override
    public void DataStore(String data) {
        addData(data);
        //數(shù)據(jù)同步
        mySql.addData(data);
    }
}

具體數(shù)據(jù)庫(kù) Redis,不需要同步到其它數(shù)據(jù)庫(kù)

public class Redis extends AbstractDatabase
{
 //給自己增加數(shù)據(jù)的方法
    @Override
    public void addData(String data)
    {
        System.out.println("====向Redis數(shù)據(jù)庫(kù)增加一條數(shù)據(jù)====");
        System.out.println("增加的數(shù)據(jù)為:"+data);
        System.out.println("=====================================");
        datas.add(data);
    }
}

客戶端測(cè)試:

public class Client
{
    public static void main(String[] args) {
        Elasticsearch elasticsearch=new Elasticsearch();
        MySql mySql=new MySql();
        Redis redis=new Redis();
        elasticsearch.setMySql(mySql);
        mySql.setElasticsearch(elasticsearch);
        mySql.setRedis(redis);
        //增加數(shù)據(jù)
        mySql.DataStore("大忽悠");
        elasticsearch.DataStore("李窈");
        redis.addData("小朋友");
        System.out.println("mysql數(shù)據(jù)庫(kù)中的數(shù)據(jù)如下:");
        mySql.display();
        System.out.println("elasticsearch數(shù)據(jù)庫(kù)中的數(shù)據(jù)如下:");
        elasticsearch.display();
        System.out.println("redis數(shù)據(jù)庫(kù)中數(shù)據(jù)如下:");
        redis.display();
    }
}

在這里插入圖片描述

其實(shí)這樣已經(jīng)實(shí)現(xiàn)了我們的需求,但是存在一些問(wèn)題

  • 系統(tǒng)結(jié)構(gòu)復(fù)雜且耦合度高。數(shù)據(jù)源需要維護(hù)目標(biāo)端數(shù)據(jù)庫(kù)的引用,以便完成數(shù)據(jù)同步
  • 組件的可重用性差。由于每一個(gè)數(shù)據(jù)源和目標(biāo)端之間具有很強(qiáng)的關(guān)聯(lián),若沒(méi)有目標(biāo)端的支持,這個(gè)組件很難被另一個(gè)系統(tǒng)或模塊重用
  • 系統(tǒng)的可擴(kuò)展性差:如果需要增加、修改或刪除其中一個(gè)數(shù)據(jù)庫(kù)、將導(dǎo)致多個(gè)類的源代碼需要修改,這違反了“開(kāi)閉原則”,可擴(kuò)展性和靈活性欠佳。

中介者模式來(lái)重構(gòu),將數(shù)據(jù)同步的功能遷移到中介者中,由中介者來(lái)管理數(shù)據(jù)同步作業(yè)

抽象中介者:

//抽象中介者
@Data
public abstract class AbstractMediator {
    protected MySql mySql;
    protected Elasticsearch elasticsearch;
    protected Redis redis;
    public abstract void sync(String databaseName, String data);
}

首先還是抽象數(shù)據(jù)庫(kù)類(抽象同事類),維護(hù)了一個(gè)中介者

public abstract class AbstractDatabase
{
    public static final String MYSQL="mysql";
    public static final String Elasticsearch="elasticsearch";
    public static final String REDIS="redis";
    //保存一個(gè)中介者對(duì)象
    @Setter
    protected AbstractMediator Mediator;
    //存儲(chǔ)數(shù)據(jù)
    protected LinkedList<String> datas=new LinkedList<>();
    //向自己的數(shù)據(jù)庫(kù)中增加數(shù)據(jù)的方法
    public abstract void addData(String data);
    //同步數(shù)據(jù)的方法--默認(rèn)空實(shí)現(xiàn)
    public void DataStore(String data){}
    //展示當(dāng)前數(shù)據(jù)庫(kù)所有數(shù)據(jù)
    public void display()
    {
        datas.forEach(x->System.out.println(x));
    }
}

Mysql 數(shù)據(jù)庫(kù)(具體同事類)

public class MySql extends AbstractDatabase
{
     //向自己的數(shù)據(jù)庫(kù)增加數(shù)據(jù)
    @Override
    public void addData(String data)
    {
        System.out.println("====向Mysql數(shù)據(jù)庫(kù)增加一條數(shù)據(jù)====");
        System.out.println("增加的數(shù)據(jù)為:"+data);
        System.out.println("=====================================");
        datas.add(data);
    }
     //重寫父類數(shù)據(jù)同步的方法
    @Override
    public void DataStore(String data)
    {
        addData(data);
       //將數(shù)據(jù)同步到redis和elasticsearch的工作由中介完成
        mediator.sync(AbstractDatabase.MYSQL,data);
    }
}

Redis 數(shù)據(jù)庫(kù)(具體同事類)

public class Redis extends AbstractDatabase
{
 //給自己增加數(shù)據(jù)的方法
    @Override
    public void addData(String data)
    {
        System.out.println("====向Redis數(shù)據(jù)庫(kù)增加一條數(shù)據(jù)====");
        System.out.println("增加的數(shù)據(jù)為:"+data);
        System.out.println("=====================================");
        datas.add(data);
    }
 //重新父類同步數(shù)據(jù)的方法
    @Override
    public void DataStore(String data) {
        addData(data);
        //同步數(shù)據(jù)的工作交給中介
        mediator.sync(AbstractDatabase.REDIS,data);
    }
}

Elasticsearch(具體同事類)

public class Elasticsearch  extends AbstractDatabase
{
    //給自己增加數(shù)據(jù)的方法
    @Override
    public void addData(String data)
    {
        System.out.println("====向Elasticsearch數(shù)據(jù)庫(kù)增加一條數(shù)據(jù)====");
        System.out.println("增加的數(shù)據(jù)為:"+data);
        System.out.println("=====================================");
        datas.add(data);
    }
    //重寫父類數(shù)據(jù)同步的方法
    @Override
    public void DataStore(String data) {
        addData(data);
        //數(shù)據(jù)同步
        mediator.sync(AbstractDatabase.Elasticsearch,data);
    }
}

具體中介者:

public class SyncMediator extends AbstractMediator {
    @Override
    public void sync(String databaseName, String data) {
        if (AbstractDatabase.MYSQL.equals(databaseName)) {
            // mysql 同步到 redis 和 Elasticsearch
            this.redis.addData(data);
            this.elasticsearch.addData(data);
        } else if (AbstractDatabase.REDIS.equals(databaseName)) {
            // redis 緩存同步,不需要同步到其他數(shù)據(jù)庫(kù)
        } else if (AbstractDatabase.Elasticsearch.equals(databaseName)) {
            // Elasticsearch 同步到 Mysql
            this.mySql.addData(data);
        }
    }
}

測(cè)試客戶端

public class Client
{
    public static void main(String[] args) {
        AbstractMediator mediator=new SyncMediator();

        Elasticsearch elasticsearch=new Elasticsearch();
        MySql mySql=new MySql();
        Redis redis=new Redis();

        elasticsearch.setMediator(mediator);
        mySql.setMediator(mediator);
        redis.setMediator(mediator);
        mediator.setMySql(mySql);
        mediator.setElasticsearch(elasticsearch);
        mediator.setRedis(redis);

        //增加數(shù)據(jù)
        mySql.DataStore("大忽悠");
        elasticsearch.DataStore("李窈");
        redis.DataStore("小朋友");
        System.out.println("mysql數(shù)據(jù)庫(kù)中的數(shù)據(jù)如下:");
        mySql.display();
        System.out.println("elasticsearch數(shù)據(jù)庫(kù)中的數(shù)據(jù)如下:");
        elasticsearch.display();
        System.out.println("redis數(shù)據(jù)庫(kù)中數(shù)據(jù)如下:");
        redis.display();
    }
}

在這里插入圖片描述

小結(jié)

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

  • 中介者模式簡(jiǎn)化了對(duì)象之間的交互,它用中介者和同事的一對(duì)多交互代替了原來(lái)同事之間的多對(duì)多交互,一對(duì)多關(guān)系更容易理解、維護(hù)和擴(kuò)展,將原本難以理解的網(wǎng)狀結(jié)構(gòu)轉(zhuǎn)換成相對(duì)簡(jiǎn)單的星型結(jié)構(gòu)。
  • 中介者模式可將各同事對(duì)象解耦。中介者有利于各同事之間的松耦合,我們可以獨(dú)立的改變和復(fù)用每一個(gè)同事和中介者,增加新的中介者和新的同事類都比較方便,更好地符合 “開(kāi)閉原則”。
  • 可以減少子類生成,中介者將原本分布于多個(gè)對(duì)象間的行為集中在一起,改變這些行為只需生成新的中介者子類即可,這使各個(gè)同事類可被重用,無(wú)須對(duì)同事類進(jìn)行擴(kuò)展。

中介者模式的主要缺點(diǎn)

  • 在具體中介者類中包含了大量同事之間的交互細(xì)節(jié),可能會(huì)導(dǎo)致具體中介者類非常復(fù)雜,使得系統(tǒng)難以維護(hù)。(也就是把具體同事類之間的交互復(fù)雜性集中到了中介者類中,結(jié)果中介者成了最復(fù)雜的類)

適用場(chǎng)景

  • 系統(tǒng)中對(duì)象之間存在復(fù)雜的引用關(guān)系,系統(tǒng)結(jié)構(gòu)混亂且難以理解。
  • 一個(gè)對(duì)象由于引用了其他很多對(duì)象并且直接和這些對(duì)象通信,導(dǎo)致難以復(fù)用該對(duì)象。
  • 想通過(guò)一個(gè)中間類來(lái)封裝多個(gè)類中的行為,而又不想生成太多的子類??梢酝ㄟ^(guò)引入中介者類來(lái)實(shí)現(xiàn),在中介者中定義對(duì)象交互的公共行為,如果需要改變行為則可以增加新的具體中介者類

具體應(yīng)用

Java Timer 中的中介者模式

敲一個(gè) java.util.Timer 的Demo

兩個(gè)任務(wù)類

public class MyOneTask extends TimerTask {
    private static int num = 0;
    @Override
    public void run() {
        System.out.println("I'm MyOneTask " + ++num);
    }
}
public class MyTwoTask extends TimerTask {
    private static int num = 1000;
    @Override
    public void run() {
        System.out.println("I'm MyTwoTask " + num--);
    }
}

客戶端測(cè)試,3秒后開(kāi)始執(zhí)行,循環(huán)周期為 1秒

public class TimerTest {
    public static void main(String[] args) {
        // 注意:多線程并行處理定時(shí)任務(wù)時(shí),Timer運(yùn)行多個(gè)TimeTask時(shí),只要其中之一沒(méi)有捕獲拋出的異常,
        // 其它任務(wù)便會(huì)自動(dòng)終止運(yùn)行,使用ScheduledExecutorService則沒(méi)有這個(gè)問(wèn)題
        Timer timer = new Timer();
        timer.schedule(new MyOneTask(), 3000, 1000); // 3秒后開(kāi)始運(yùn)行,循環(huán)周期為 1秒
        timer.schedule(new MyTwoTask(), 3000, 1000);
    }
}

Timer 的部分關(guān)鍵源碼如下

public class Timer {
    private final TaskQueue queue = new TaskQueue();
    private final TimerThread thread = new TimerThread(queue);
    public void schedule(TimerTask task, long delay) {
        if (delay < 0)
            throw new IllegalArgumentException("Negative delay.");
        sched(task, System.currentTimeMillis()+delay, 0);
    }
    public void schedule(TimerTask task, Date time) {
        sched(task, time.getTime(), 0);
    }
    private void sched(TimerTask task, long time, long period) {
        if (time < 0)
            throw new IllegalArgumentException("Illegal execution time.");
        if (Math.abs(period) > (Long.MAX_VALUE >> 1))
            period >>= 1;
        // 獲取任務(wù)隊(duì)列的鎖(同一個(gè)線程多次獲取這個(gè)鎖并不會(huì)被阻塞,不同線程獲取時(shí)才可能被阻塞)
        synchronized(queue) {
            // 如果定時(shí)調(diào)度線程已經(jīng)終止了,則拋出異常結(jié)束
            if (!thread.newTasksMayBeScheduled)
                throw new IllegalStateException("Timer already cancelled.");
            // 再獲取定時(shí)任務(wù)對(duì)象的鎖(為什么還要再加這個(gè)鎖呢?想不清)
            synchronized(task.lock) {
                // 判斷線程的狀態(tài),防止多線程同時(shí)調(diào)度到一個(gè)任務(wù)時(shí)多次被加入任務(wù)隊(duì)列
                if (task.state != TimerTask.VIRGIN)
                    throw new IllegalStateException(
                        "Task already scheduled or cancelled");
                // 初始化定時(shí)任務(wù)的下次執(zhí)行時(shí)間
                task.nextExecutionTime = time;
                // 重復(fù)執(zhí)行的間隔時(shí)間
                task.period = period;
                // 將定時(shí)任務(wù)的狀態(tài)由TimerTask.VIRGIN(一個(gè)定時(shí)任務(wù)的初始化狀態(tài))設(shè)置為TimerTask.SCHEDULED
                task.state = TimerTask.SCHEDULED;
            }
            // 將任務(wù)加入任務(wù)隊(duì)列
            queue.add(task);
            // 如果當(dāng)前加入的任務(wù)是需要第一個(gè)被執(zhí)行的(也就是他的下一次執(zhí)行時(shí)間離現(xiàn)在最近)
            // 則喚醒等待queue的線程(對(duì)應(yīng)到上面提到的queue.wait())
            if (queue.getMin() == task)
                queue.notify();
        }
    }
    // cancel會(huì)等到所有定時(shí)任務(wù)執(zhí)行完后立刻終止定時(shí)線程
    public void cancel() {
        synchronized(queue) {
            thread.newTasksMayBeScheduled = false;
            queue.clear();
            queue.notify();  // In case queue was already empty.
        }
    }
    // ...
}

Timer 中在 schedulexxx 方法中通過(guò) TaskQueue 協(xié)調(diào)各種 TimerTask 定時(shí)任務(wù),Timer 是中介者,TimerTask 是抽象同事類,而我們自己寫的任務(wù)則是具體同事類

TimerThread Timer 中定時(shí)調(diào)度線程類的定義,這個(gè)類會(huì)做為一個(gè)線程一直運(yùn)行來(lái)執(zhí)行 Timer 中任務(wù)隊(duì)列中的任務(wù)。

Timer 這個(gè)中介者的功能就是定時(shí)調(diào)度我們寫的各種任務(wù),將任務(wù)添加到 TaskQueue 任務(wù)隊(duì)列中,給 TimerThread 執(zhí)行,讓任務(wù)與執(zhí)行線程解耦

參考文章

設(shè)計(jì)模式之中介者模式

23種設(shè)計(jì)模式(7):中介者模式

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

相關(guān)文章

  • SpringBoot獲取不到用戶真實(shí)IP的解決方法

    SpringBoot獲取不到用戶真實(shí)IP的解決方法

    最近遇到個(gè)問(wèn)題,項(xiàng)目部署后發(fā)現(xiàn)服務(wù)端無(wú)法獲取到客戶端真實(shí)的IP地址,本文就來(lái)介紹一下這個(gè)問(wèn)題的解決方法,感興趣的可以了解一下
    2023-08-08
  • Java如何實(shí)現(xiàn)讀取txt文件內(nèi)容并生成Word文檔

    Java如何實(shí)現(xiàn)讀取txt文件內(nèi)容并生成Word文檔

    本文主要介紹了通過(guò)Java實(shí)現(xiàn)讀取txt文件中的內(nèi)容,并將內(nèi)容生成Word文檔。文章的代碼非常詳細(xì),具有一定的學(xué)習(xí)價(jià)值,感興趣的小伙伴可以了解一下
    2021-12-12
  • 淺談利用Spring的AbstractRoutingDataSource解決多數(shù)據(jù)源的問(wèn)題

    淺談利用Spring的AbstractRoutingDataSource解決多數(shù)據(jù)源的問(wèn)題

    本篇文章主要介紹了淺談利用Spring的AbstractRoutingDataSource解決多數(shù)據(jù)源的問(wèn)題,具有一定的參考價(jià)值,有需要的可以了解一下
    2017-08-08
  • java文件上傳下載代碼實(shí)例

    java文件上傳下載代碼實(shí)例

    這篇文章主要介紹了java文件上傳下載,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2019-03-03
  • 詳解Spring如何更簡(jiǎn)單的讀取和存儲(chǔ)對(duì)象

    詳解Spring如何更簡(jiǎn)單的讀取和存儲(chǔ)對(duì)象

    這篇文章主要為大家詳細(xì)介紹了Spring中如何更簡(jiǎn)單的實(shí)現(xiàn)讀取和存儲(chǔ)對(duì)象,文中的示例代碼講解詳細(xì),感興趣的小伙伴可以跟隨小編一起學(xué)習(xí)一下
    2023-07-07
  • 重新認(rèn)識(shí)Java的System.in

    重新認(rèn)識(shí)Java的System.in

    今天小編就為大家分享一篇關(guān)于重新認(rèn)識(shí)Java的System.in,小編覺(jué)得內(nèi)容挺不錯(cuò)的,現(xiàn)在分享給大家,具有很好的參考價(jià)值,需要的朋友一起跟隨小編來(lái)看看吧
    2018-12-12
  • spring中的注入list集合

    spring中的注入list集合

    這篇文章主要介紹了spring中的注入list集合問(wèn)題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2022-11-11
  • java 獲取服務(wù)器真實(shí)IP的實(shí)例

    java 獲取服務(wù)器真實(shí)IP的實(shí)例

    這篇文章主要介紹了java 獲取服務(wù)器真實(shí)IP的實(shí)例的相關(guān)資料,這里提供實(shí)現(xiàn)方法幫助大家學(xué)習(xí)理解這部分內(nèi)容,需要的朋友可以參考下
    2017-08-08
  • SpringBoot創(chuàng)建RSocket服務(wù)器的全過(guò)程記錄

    SpringBoot創(chuàng)建RSocket服務(wù)器的全過(guò)程記錄

    RSocket應(yīng)用層協(xié)議支持 Reactive Streams語(yǔ)義, 例如:用RSocket作為HTTP的一種替代方案。這篇文章主要給大家介紹了關(guān)于SpringBoot創(chuàng)建RSocket服務(wù)器的相關(guān)資料,需要的朋友可以參考下
    2021-05-05
  • Java list與set中contains()方法效率案例詳解

    Java list與set中contains()方法效率案例詳解

    這篇文章主要介紹了Java list與set中contains()方法效率案例詳解,本篇文章通過(guò)簡(jiǎn)要的案例,講解了該項(xiàng)技術(shù)的了解與使用,以下就是詳細(xì)內(nèi)容,需要的朋友可以參考下
    2021-08-08

最新評(píng)論