laravel服務(wù)容器--深入理解控制反轉(zhuǎn)(IoC)和依賴(lài)注入(DI)

首先大家想一想什么是容器,字面意思就是盛放東西的東西,常見(jiàn)的變量,對(duì)象屬性都是容器,一個(gè)容器能夠裝什么東西,完全在于你對(duì)這個(gè)容器的定義。有的容器不僅僅只是存文本,變量,而是對(duì)象,屬性,那么我們通過(guò)這種容器就可以進(jìn)行很多高級(jí)的功能。

IoC容器

IoC容器是laravel的核心,它提供了框架需要的一系列的服務(wù),文檔上稱(chēng)他為服務(wù)容器,解釋為一個(gè)用于管理類(lèi)依賴(lài)和執(zhí)行依賴(lài)注入的強(qiáng)大工具,聽(tīng)起來(lái)暈暈乎乎的,之后在文檔中找到一片文章:http://laravelacademy.org/post/769.html。我寫(xiě)這篇文章也是為了更好的理解什么 是控制反轉(zhuǎn)和依賴(lài)注入。

依賴(lài)的產(chǎn)生----超人和超能力

在面向?qū)ο蟮木幊讨校傄佑|幾個(gè)東西:接口,類(lèi),對(duì)象。接口是類(lèi)的原型,一個(gè)類(lèi)一定要遵守實(shí)現(xiàn)的接口,對(duì)象則是一個(gè)類(lèi)實(shí)例化的產(chǎn)物。這樣子說(shuō)不利于理解,我們可以舉一個(gè)例子。

  • 一個(gè)怪物橫行的世界里,我們需要超人來(lái)戰(zhàn)勝怪獸,維護(hù)世界和平。

我們把超人當(dāng)做一個(gè)類(lèi):

class SuperMan {}

我們可以想一下,一個(gè)超人誕生的時(shí)候肯定有至少有一個(gè)超能力,我們可以把這個(gè)超能力也抽象為一個(gè)對(duì)象,一個(gè)超能力肯定有多種屬性,以及操作方法,我們先大致定義一個(gè)只有屬性的類(lèi),至于方法,我們可以到后面進(jìn)行補(bǔ)充:

class Power {
  protected $ability;  //能力值`
  protected $range;   //能力范圍`
  public  function  ____construct($ability,$range) {
    $this->ability = $ability;
    $this->range = $range;
  }
}

這時(shí)我們可以回去修改一下超人類(lèi),讓在超人被創(chuàng)建的時(shí)候賦予一個(gè)超能力:

class  SuperMan  {
  protected  $power;
  public  function  __construct() {
    $this->power = new  Power(999,999);
  }
}

這樣子,超人在創(chuàng)建的時(shí)候就有了超能力,我們這個(gè)時(shí)候可以發(fā)現(xiàn),超人 和超能力之間現(xiàn)在存在一種依賴(lài),怎么體現(xiàn)出這個(gè)依賴(lài)了呢,所謂依賴(lài),就是我若依賴(lài)了你,那我就離不開(kāi)你。在面向?qū)ο蟮木幊讨校@種依賴(lài)隨處可見(jiàn),少量的依賴(lài)并不影響什么,但是當(dāng)在一個(gè)項(xiàng)目中,這種依賴(lài)達(dá)到一種量級(jí)的時(shí)候,那會(huì)舉步維艱!

之前的例子中,超能力類(lèi)實(shí)例化后是一個(gè)具體的超能力,但是我們知道,超人的超能力是多元化的,每種超能力的方法、屬性都有不小的差異,沒(méi)法通過(guò)一種類(lèi)描述完全。我們現(xiàn)在進(jìn)行修改,我們假設(shè)超人可以有以下多種超能力:

  • 飛行,屬性有:飛行速度、持續(xù)飛行時(shí)間
  • 蠻力,屬性有:力量值
  • 能量彈,屬性有:傷害值、射擊距離、同時(shí)射擊個(gè)數(shù)

我們會(huì)創(chuàng)建這些類(lèi):

class  Flight  {
  protected  $speed;
  protected  $holdtime;
  public  function  __construct($speed, $holdtime) {}
 }

class  Force  {
  protected  $force;
  public  function  __construct($force) {}
}

class  Shot  {
  protected  $atk;
  protected  $range;
  protected  $limit;
  public  function  __construct( $atk, $range, $limit) {}
}

那么此時(shí),超人在創(chuàng)建的時(shí)候,我們會(huì)根據(jù)需要來(lái)進(jìn)行初始化超能力,如下:

class  Superman  {
  protected  $power;
  public  function  __construct()  {
    $this->power = new  Fight(9, 100);
    // $this->power = new Force(45);
    // $this->power = new Shot(99, 50, 2);
    /*
    $this->power = array(
      new Force(45),
      new Shot(99, 50, 2)
    );
    */
  }
}

我們需要手動(dòng)在構(gòu)造函數(shù)或者其他方法中實(shí)例化一系列的類(lèi),這樣子真的好嗎?可以想想,當(dāng)不同的怪獸侵略地球,我們需要不同超能力的超人更好的打敗怪獸時(shí),我們血藥重新改造超人,換句話說(shuō),改變超能力的同時(shí),我們還需要重新創(chuàng)建一個(gè)超人。這樣子的效率是不是太低了呢,我們還有什么更好的方法呢?

看過(guò)鋼鐵俠的人都知道鋼鐵俠可以隨時(shí)更換自己的智能芯片,那么我們是不是可以讓超人的超能力可以隨時(shí)更換,只需要更換一種裝置或者芯片呢?之前我們是在超人類(lèi)中固化了他的超能力初始化的行為,如果我們要實(shí)現(xiàn)通過(guò)更換芯片來(lái)改變超人的超能力,那么就應(yīng)該將超能力初始化行為轉(zhuǎn)為由外部進(jìn)行,由外部創(chuàng)建超能力模組,然后植入超人體內(nèi)一個(gè)特定的接口,只要那些超能力模組能夠滿(mǎn)足這個(gè)接口都可以被超人利用,增大超人的能力。這種由外部負(fù)責(zé)其依賴(lài)需求的行為,我們可以稱(chēng)其為 “控制反轉(zhuǎn)(IoC)”。

工廠模式,依賴(lài)轉(zhuǎn)移!

在實(shí)現(xiàn)控制反轉(zhuǎn)前,我們可以思考思考:我們可以想到,組件、工具(或者超人的模組),是一種可被生產(chǎn)的玩意兒,生產(chǎn)的地方當(dāng)然是 “工廠(Factory)”,于是有人就提出了這樣一種模式: 工廠模式。

工廠模式,顧名思義,就是一個(gè)類(lèi)所依賴(lài)的外部事物的實(shí)例,都可以被一個(gè)或多個(gè) “工廠” 創(chuàng)建的這樣一種開(kāi)發(fā)模式,就是 “工廠模式”。

我們?yōu)榱私o超人制造超能力模組,我們創(chuàng)建了一個(gè)工廠,它可以制造各種各樣的模組,且僅需要通過(guò)一個(gè)方法:

class SuperModuleFactory
{
     public function makeModule($moduleName, $options) {
          switch ($moduleName) {
            case 'Fight':
                return new Fight($options[0], $options[1]);
            case 'Force':
                return new Force($options[0]);
            case 'Shot':
                return new Shot($options[0], $options[1], $options[2]);
        }
     }
}

這時(shí)候,超人 創(chuàng)建之初就可以使用這個(gè)工廠:

class Superman
{
    protected $power;
 
    public function __construct()
    {
        // 初始化工廠
        $factory = new SuperModuleFactory;
 
        // 通過(guò)工廠提供的方法制造需要的模塊
        $this->power = $factory->makeModule('Fight', [9, 100]);
        // $this->power = $factory->makeModule('Force', [45]);
        // $this->power = $factory->makeModule('Shot', [99, 50, 2]);
        /*
        $this->power = array(
            $factory->makeModule('Force', [45]),
            $factory->makeModule('Shot', [99, 50, 2])
        );
        */
    }
}

可以看得出,我們不再需要在超人初始化之初,去初始化許多第三方類(lèi),只需初始化一個(gè)工廠類(lèi),即可滿(mǎn)足需求。但這樣似乎和以前區(qū)別不大,只是沒(méi)有那么多 new 關(guān)鍵字。其實(shí)我們稍微改造一下這個(gè)類(lèi),你就明白,工廠類(lèi)的真正意義和價(jià)值了!

class Superman
{
    protected $power;
 
    public function __construct(array $modules)
    {
        // 初始化工廠
        $factory = new SuperModuleFactory;
 
        // 通過(guò)工廠提供的方法制造需要的模塊
        foreach ($modules as $moduleName => $moduleOptions) {
            $this->power[] = $factory->makeModule($moduleName, $moduleOptions);
        }
    }
}
 
// 創(chuàng)建超人
$superman = new Superman([
    'Fight' => [9, 100],
    'Shot' => [99, 50, 2]
]);

現(xiàn)在,“超人” 的創(chuàng)建不再依賴(lài)任何一個(gè) “超能力” 的類(lèi),我們?nèi)缛粜薷牧嘶蛘咴黾恿诵碌某芰?,只需要針?duì)修改 SuperModuleFactory 即可。擴(kuò)充超能力的同時(shí)不再需要重新編輯超人的類(lèi)文件,使得我們變得很輕松。但是,這才剛剛開(kāi)始。

IoC 容器的重要組成 —— 依賴(lài)注入

由 “超人” 對(duì) “超能力” 的依賴(lài)變成 “超人” 對(duì) “超能力模組工廠” 的依賴(lài)后,對(duì)付小怪獸們變得更加得心應(yīng)手。但這也正如你所看到的,依賴(lài)并未解除,只是由原來(lái)對(duì)多個(gè)外部的依賴(lài)變成了對(duì)一個(gè) “工廠” 的依賴(lài)。假如工廠出了點(diǎn)麻煩,問(wèn)題變得就很棘手。其實(shí)大多數(shù)情況下,工廠模式已經(jīng)足夠了。工廠模式的缺點(diǎn)就是:接口未知(即沒(méi)有一個(gè)很好的契約模型,關(guān)于這個(gè)我馬上會(huì)有解釋?zhuān)?、產(chǎn)生對(duì)象類(lèi)型單一??傊褪?,還是不夠靈活。雖然如此,工廠模式依舊十分優(yōu)秀,并且適用于絕大多數(shù)情況。

我們知道,超人依賴(lài)的模組,我們要求有統(tǒng)一的接口,這樣才能和超人身上的注入接口對(duì)接,最終起到提升超能力的效果。其實(shí)侵略地球的不僅僅只有這一點(diǎn)小怪獸,后面還有很多大怪獸,這個(gè)時(shí)候我們的工廠好像有點(diǎn)力不從心了,因?yàn)槊看我绿钜粋€(gè)超能力,總是要對(duì)工廠進(jìn)行維修和翻新,相當(dāng)于增加生產(chǎn)線。是不是感覺(jué)還是很是噩夢(mèng),下一步就是我們今天的主要配角 —— DI (依賴(lài)注入)

由于對(duì)超能力模組的需求不斷增大,我們需要集合整個(gè)世界的高智商人才,一起解決問(wèn)題,不應(yīng)該僅僅只有幾個(gè)工廠壟斷負(fù)責(zé)。不過(guò)高智商人才們都非常自負(fù),認(rèn)為自己的想法是對(duì)的,創(chuàng)造出的超能力模組沒(méi)有統(tǒng)一的接口,自然而然無(wú)法被正常使用。這時(shí)我們需要提出一種契約,這樣無(wú)論是誰(shuí)創(chuàng)造出的模組,都符合這樣的接口,自然就可被正常使用。

interface SuperModuleInterface
{
    /**
     * 超能力激活方法
     *
     * 任何一個(gè)超能力都得有該方法,并擁有一個(gè)參數(shù)
     *@param array $target 針對(duì)目標(biāo),可以是一個(gè)或多個(gè),自己或他人
     */
    public function activate(array $target);
}

上文中,我們定下了一個(gè)超能力接口(模組規(guī)范),所有被創(chuàng)建的模組必須遵守這個(gè)契約才能被生產(chǎn)和使用。

可能大家對(duì)于在php中出現(xiàn)接口這種東西感到很是驚奇,這種東西不是只有在java,c++中才有的嗎,其實(shí)對(duì)于任何一款面向?qū)ο蟮木幊陶Z(yǔ)言,接口都是存在并且有很大作用的。因?yàn)橐粋€(gè)對(duì)象,都是由他的模板或者原型---類(lèi)經(jīng)過(guò)實(shí)例化后的一個(gè)具體事物,有時(shí)候,要實(shí)現(xiàn)統(tǒng)一方法但具有不同功能或特性的時(shí)候,需要很多類(lèi),這個(gè)時(shí)候就需要一個(gè)契約,讓大家編寫(xiě)出可以隨時(shí)替換但又不會(huì)產(chǎn)生影響的接口,這種由編程語(yǔ)言本身提出的硬性規(guī)范,會(huì)增加更多優(yōu)秀的特性。大家之后就會(huì)懂得接口的好處。

在這個(gè)模組被提出來(lái)之后,高智商的科學(xué)家們遵循這個(gè)接口,創(chuàng)建了很多類(lèi):

/**
 * X-超能量
 */
class XPower implements SuperModuleInterface
{
    public function activate(array $target)
    {
        // 這只是個(gè)例子。。具體自行腦補(bǔ)
    }
}
 
/**
 * 終極炸彈
 */
class UltraBomb implements SuperModuleInterface
{
    public function activate(array $target)
    {
        // 這只是個(gè)例子。。具體自行腦補(bǔ)
    }
}

同時(shí),為了防止一些科學(xué)家不遵守這個(gè)接口進(jìn)行惡意的搗亂,我們現(xiàn)在要修改之前的超人類(lèi):

class Superman
{
    protected $module;
 
    public function __construct(SuperModuleInterface $module)
    {
        $this->module = $module;
    }
}

改造完畢!現(xiàn)在,當(dāng)我們初始化 “超人” 類(lèi)的時(shí)候,提供的模組實(shí)例必須是一個(gè) SuperModuleInterface 接口的實(shí)現(xiàn)。否則就會(huì)提示錯(cuò)誤。

正是由于超人的創(chuàng)造變得容易,一個(gè)超人也就不需要太多的超能力,我們可以創(chuàng)造多個(gè)超人,并分別注入需要的超能力模組即可。這樣的話,雖然一個(gè)超人只有一個(gè)超能力,但超人更容易變多,我們也不怕怪獸啦!

現(xiàn)在有人疑惑了,你要講的依賴(lài)注入呢?

其實(shí),上面講的內(nèi)容,正是依賴(lài)注入。

什么叫做依賴(lài)注入?

從本文開(kāi)頭到現(xiàn)在提出來(lái)一系列依賴(lài),只要不是由內(nèi)部生產(chǎn)(比如初始化、構(gòu)造函數(shù) __construct 中通過(guò)工廠方法、自行手動(dòng) new 的),而是由外部以參數(shù)或其他形式注入的,都屬于依賴(lài)注入(DI) 。是不是豁然開(kāi)朗?事實(shí)上,就是這么簡(jiǎn)單。下面就是一個(gè)典型的依賴(lài)注入:

// 超能力模組
$superModule = new XPower;
// 初始化一個(gè)超人,并注入一個(gè)超能力模組依賴(lài)
$superMan = new Superman($superModule);

更為先進(jìn)的工廠 —— IoC 容器

剛剛列了一串代碼:

// 超能力模組
$superModule = new XPower;
// 初始化一個(gè)超人,并注入一個(gè)超能力模組依賴(lài)
$superMan = new Superman($superModule);

現(xiàn)在我們能發(fā)現(xiàn),這是手動(dòng)的創(chuàng)建一個(gè)超人和超能力模板,并且將模板注入剛剛創(chuàng)建的超人當(dāng)中,然而,現(xiàn)代社會(huì),應(yīng)該是高效率的生產(chǎn),干凈的車(chē)間,完美的自動(dòng)化裝配!

我們需要自動(dòng)化 —— 最多一條指令,千軍萬(wàn)馬來(lái)相見(jiàn)。我們需要一種高級(jí)的生產(chǎn)車(chē)間,我們只需要向生產(chǎn)車(chē)間提交一個(gè)腳本,工廠便能夠通過(guò)指令自動(dòng)化生產(chǎn)。這樣子,當(dāng)一大堆怪獸來(lái)了我們只需要一條指令就有千軍萬(wàn)馬來(lái)相見(jiàn)。這種更為高級(jí)的工廠,就是工廠模式的升華 —— IoC 容器。

class Container
{
    protected $binds;
 
    protected $instances;
 
    public function bind($abstract, $concrete)
    {
        if ($concrete instanceof Closure) {//instanceof Closure 判斷是否為閉包
            $this->binds[$abstract] = $concrete;
        } else {
            $this->instances[$abstract] = $concrete;
        }
    }
 
    public function make($abstract, $parameters = [])
    {
        if (isset($this->instances[$abstract])) {
            return $this->instances[$abstract];
        }

        //把$this插入到$parameters數(shù)組的開(kāi)頭
        array_unshift($parameters, $this);
 
        //call_user_func_array(callback $callback,array $param_arr)
        //$callback=回調(diào)函數(shù)
        //$param_arr=傳入回調(diào)函數(shù)的參數(shù),按照順序傳入
        return call_user_func_array($this->binds[$abstract], $parameters);
    }
}

這時(shí)候,一個(gè)十分粗糙的容器就誕生了?,F(xiàn)在的確很簡(jiǎn)陋,但不妨礙我們進(jìn)一步提升他。先著眼現(xiàn)在,看看這個(gè)容器如何使用吧!

// 創(chuàng)建一個(gè)容器(后面稱(chēng)作超級(jí)工廠)
$container = new Container;
 
// 向該 超級(jí)工廠添加超人的生產(chǎn)腳本
$container->bind('superman', function($container, $moduleName) {
    return new Superman($container->make($moduleName));
});
 
// 向該 超級(jí)工廠添加超能力模組的生產(chǎn)腳本
$container->bind('xpower', function($container) {
    return new XPower;
});
 
// 同上
$container->bind('ultrabomb', function($container) {
    return new UltraBomb;
});
 
// ****************** 華麗麗的分割線 **********************
// 開(kāi)始啟動(dòng)生產(chǎn)
$superman_1 = $container->make('superman', 'xpower');
$superman_2 = $container->make('superman', 'ultrabomb');
$superman_3 = $container->make('superman', 'xpower');
// ...隨意添加

看到?jīng)]?通過(guò)最初的 綁定(bind) 操作,我們向 超級(jí)工廠 注冊(cè)了一些生產(chǎn)腳本,這些生產(chǎn)腳本在生產(chǎn)指令下達(dá)之時(shí)便會(huì)執(zhí)行。發(fā)現(xiàn)沒(méi)有?我們徹底的解除了 超人 與 超能力模組 的依賴(lài)關(guān)系,更重要的是,容器類(lèi)也絲毫沒(méi)有和他們產(chǎn)生任何依賴(lài)!我們通過(guò)注冊(cè)、綁定的方式向容器中添加一段可以被執(zhí)行的回調(diào)(可以是匿名函數(shù)、非匿名函數(shù)、類(lèi)的方法)作為生產(chǎn)一個(gè)類(lèi)的實(shí)例的 腳本 ,只有在真正的 生產(chǎn)(make) 操作被調(diào)用執(zhí)行時(shí),才會(huì)觸發(fā)。這樣一種方式,使得我們更容易在創(chuàng)建一個(gè)實(shí)例的同時(shí)解決其依賴(lài)關(guān)系,并且更加靈活。當(dāng)有新的需求,只需另外綁定一個(gè)“生產(chǎn)腳本”即可。

實(shí)際上,真正的 IoC 容器更為高級(jí)。我們現(xiàn)在的例子中,還是需要手動(dòng)提供超人所需要的模組參數(shù),但真正的 IoC 容器會(huì)根據(jù)類(lèi)的依賴(lài)需求,自動(dòng)在注冊(cè)、綁定的一堆實(shí)例中搜尋符合的依賴(lài)需求,并自動(dòng)注入到構(gòu)造函數(shù)參數(shù)中去。Laravel 框架的服務(wù)容器正是這么做的。實(shí)現(xiàn)這種功能其實(shí)理論上并不麻煩。

現(xiàn)在,到目前為止,我們已經(jīng)不再懼怕怪獸們了。高智商人才集思廣益,井井有條,根據(jù)接口契約創(chuàng)造規(guī)范的超能力模組。超人開(kāi)始批量產(chǎn)出。最終,人人都是超人,你也可以是哦!

重新審視 Laravel 的核心

現(xiàn)在,我們開(kāi)始慢慢解讀 Laravel 的核心。其實(shí),Laravel 的核心就是一個(gè) IoC 容器,也恰好是我之前所說(shuō)的高級(jí)的 IoC 容器。

可以說(shuō),Laravel 的核心本身十分輕量,并沒(méi)有什么很神奇很實(shí)質(zhì)性的應(yīng)用功能。很多人用到的各種功能模塊比如 Route(路由)、Eloquent ORM(數(shù)據(jù)庫(kù) ORM 組件)、Request(請(qǐng)求)以及 Response(響應(yīng))等等等等,實(shí)際上都是與核心無(wú)關(guān)的類(lèi)模塊提供的,這些類(lèi)從注冊(cè)到實(shí)例化,最終被你所使用,其實(shí)都是 Laravel 的服務(wù)容器負(fù)責(zé)的。

我們以大家最常見(jiàn)的 Route 類(lèi)作為例子。大家可能經(jīng)常見(jiàn)到路由定義是這樣的:

Route::get('/', function() {
    // bla bla bla...
});

實(shí)際上, Route 類(lèi)被定義在這個(gè)命名空間:Illuminate\Routing\Router,文件 vendor/laravel/framework/src/Illuminate/Routing/Router.php,

服務(wù)提供者

我們?cè)谇拔慕榻B IoC 容器的部分中,提到了,一個(gè)類(lèi)需要綁定、注冊(cè)至容器中,才能被“制造”。

對(duì),一個(gè)類(lèi)要被容器所能夠提取,必須要先注冊(cè)至這個(gè)容器。既然 Laravel 稱(chēng)這個(gè)容器叫做服務(wù)容器,那么我們需要某個(gè)服務(wù),就得先注冊(cè)、綁定這個(gè)服務(wù)到容器,那么提供服務(wù)并綁定服務(wù)至容器的東西,就是服務(wù)提供者(Service Provider)。

雖然,綁定一個(gè)類(lèi)到容器不一定非要通過(guò)服務(wù)提供者。

但是,我們知道,有時(shí)候我們的類(lèi)、模塊會(huì)有需要其他類(lèi)和組件的情況,為了保證初始化階段不會(huì)出現(xiàn)所需要的模塊和組件沒(méi)有注冊(cè)的情況,Laravel 將注冊(cè)和初始化行為進(jìn)行拆分,注冊(cè)的時(shí)候就只能注冊(cè),初始化的時(shí)候就是初始化。拆分后的產(chǎn)物就是現(xiàn)在的服務(wù)提供者。

服務(wù)提供者主要分為兩個(gè)部分,register(注冊(cè)) 和 boot(引導(dǎo)、初始化),具體參考文檔。register 負(fù)責(zé)進(jìn)行向容器注冊(cè)“腳本”,但要注意注冊(cè)部分不要有對(duì)未知事物的依賴(lài),如果有,就要移步至 boot 部分。

門(mén)面(Facade

我們現(xiàn)在解答之前關(guān)于 Route 的方法為何能以靜態(tài)方法訪問(wèn)的問(wèn)題。實(shí)際上這個(gè)問(wèn)題文檔上有寫(xiě),簡(jiǎn)單說(shuō)來(lái)就是模擬一個(gè)類(lèi),提供一個(gè)靜態(tài)魔術(shù)方法__callStatic,并將該靜態(tài)方法映射到真正的方法上。

__callStatic,__call成對(duì)理解,旨在調(diào)用類(lèi)中的方法,如果類(lèi)中有對(duì)應(yīng)的靜態(tài)/普通方法,就調(diào)用;否則就調(diào)用魔術(shù)方法中的內(nèi)容。參考:https://blog.csdn.net/sunyinggang/article/details/78906048

我們使用的 Route 類(lèi)實(shí)際上是 Illuminate\Support\Facades\Route 通過(guò) class_alias() 函數(shù)創(chuàng)造的別名而已,這個(gè)類(lèi)被定義在文件 vendor/laravel/framework/src/Illuminate/Support/Facades/Route.php 。

我們打開(kāi)文件一看……誒?怎么只有這么簡(jiǎn)單的一段代碼呢?

namespace Illuminate\Support\Facades;
 
/**
 * @see \Illuminate\Routing\Router
 */
class Route extends Facade {
 
/**
 * Get the registered name of the component.
 *
 * @return string
 */
   protected static function getFacadeAccessor() {
    return 'router';
   }
}

其實(shí)仔細(xì)看,會(huì)發(fā)現(xiàn)這個(gè)類(lèi)繼承了一個(gè)叫做 Facade 的類(lèi),到這里謎底差不多要解開(kāi)了。

上述簡(jiǎn)單的定義中,我們看到了 getFacadeAccessor 方法返回了一個(gè) route,這是什么意思呢?事實(shí)上,這個(gè)值被一個(gè) ServiceProvider 注冊(cè)過(guò),大家應(yīng)該知道注冊(cè)了個(gè)什么,當(dāng)然是那個(gè)真正的路由類(lèi)!

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容