【Laravel—核心源碼解析】服務(wù)容器解析篇

前言

上章了解了服務(wù)容器綁定篇拆魏,本章介紹通過(guò)服務(wù)容器解析實(shí)例

正文

在Laravel的服務(wù)容器中提供了兩種用于獲取服務(wù)容器中實(shí)例的方法
make及resolve

make

make在內(nèi)部是直接調(diào)用了resolve慈俯,但因?yàn)槭褂萌萜魇谴蠖嗍鞘褂肁pplication類來(lái)進(jìn)行make的所以會(huì)先執(zhí)行Application類的make,再調(diào)用到Container中的make

Application:

public function make($abstract, array $parameters = [])
{
    //獲取別名卖子,如果未配置則原樣返回
    $abstract = $this->getAlias($abstract);
    //判斷是否有延遲服務(wù)且未經(jīng)過(guò)instance綁定
    if ($this->isDeferredService($abstract) && ! isset($this->instances[$abstract])) {
        //加載延遲服務(wù)提供程序
        $this->loadDeferredProvider($abstract);
    }
    return parent::make($abstract, $parameters);
}

Container:

public function make($abstract, array $parameters = [])
{
    return $this->resolve($abstract, $parameters);
}

resolve

protected function resolve($abstract, $parameters = [], $raiseEvents = true)
{
    //getAlias方法會(huì)假定$abstract是綁定的別名刑峡,從$aliases找到映 射的真實(shí)類型名
    //如果沒(méi)有映射則$abstract即為真實(shí)類型名,將$abstract原樣返回
    $abstract = $this->getAlias($abstract);

    //獲取給定抽象的上下文具體綁定诫舅。
    $needsContextualBuild = ! empty($parameters) || ! is_null(
        $this->getContextualConcrete($abstract)
    );

    // 如果服務(wù)是通過(guò)instance()方式綁定的宫患,就直接解析返回綁定的service
    if (isset($this->instances[$abstract]) && ! $needsContextualBuild) {
        return $this->instances[$abstract];
    }

    $this->with[] = $parameters;
    //獲取綁定時(shí)存入的閉包
    $concrete = $this->getConcrete($abstract);

    //isBuildable方法:$concrete === $abstract || $concrete instanceof Closure
    if ($this->isBuildable($concrete, $abstract)) {
        //直接構(gòu)建出實(shí)例娃闲,如果是閉包就返回閉包,如果不是就通過(guò)反射類獲取出實(shí)例返回
        $object = $this->build($concrete);
    } else {
        //如果時(shí)接口實(shí)現(xiàn)這種綁定方式皇帮,通過(guò)接口拿到實(shí)現(xiàn)后需要再make一次才能
        $object = $this->make($concrete);
    }

    //獲取擴(kuò)展程序
    foreach ($this->getExtenders($abstract) as $extender) {
        $object = $extender($object, $this);
    }

    //如果服務(wù)是以singleton方式注冊(cè)進(jìn)來(lái)的則属拾,把構(gòu)建好的服務(wù)對(duì)象放到 $instances里冷溶,
    // 避免下次使用時(shí)重新構(gòu)建
    if ($this->isShared($abstract) && ! $needsContextualBuild) {
        $this->instances[$abstract] = $object;
    }

    if ($raiseEvents) {
        $this->fireResolvingCallbacks($abstract, $object);
    }

    $this->resolved[$abstract] = true;

    array_pop($this->with);

    return $object;
}

build

public function build($concrete)
{
    // 如果是閉包直接執(zhí)行閉包并返回(對(duì)應(yīng)閉包綁定)
    if ($concrete instanceof Closure) {
        return $concrete($this, $this->getLastParameterOverride());
    }

    // 使用反射ReflectionClass來(lái)對(duì)實(shí)現(xiàn)類進(jìn)行反射實(shí)例操作
    try {
        $reflector = new ReflectionClass($concrete);
    } catch (ReflectionException $e) {
        throw new BindingResolutionException("Target class [$concrete] does not exist.", 0, $e);
    }

    // 如果不能實(shí)例化瓢娜,這應(yīng)該是接口或抽象類,再或者就是構(gòu)造函數(shù)是 private的虏劲,進(jìn)行異常跑出褒颈。反之實(shí)例化操作
    if (! $reflector->isInstantiable()) {
        return $this->notInstantiable($concrete);
    }

    $this->buildStack[] = $concrete;

    // 獲取構(gòu)造函數(shù)
    $constructor = $reflector->getConstructor();

    // 如果構(gòu)造函數(shù)是空,說(shuō)明沒(méi)有任何依賴堡掏,直接new返回
    if (is_null($constructor)) {
        array_pop($this->buildStack);

        return new $concrete;
    }

    // 獲取構(gòu)造函數(shù)的依賴(形參)刨疼,返回一組ReflectionParameter對(duì)象 組成的數(shù)組表示每一個(gè)參數(shù)
    $dependencies = $constructor->getParameters();

    try {
        // 構(gòu)建構(gòu)造函數(shù)需要的依賴
        $instances = $this->resolveDependencies($dependencies);
    } catch (BindingResolutionException $e) {
        array_pop($this->buildStack);

        throw $e;
    }

    array_pop($this->buildStack);

    //從給出的參數(shù)創(chuàng)建一個(gè)新的類實(shí)例
    return $reflector->newInstanceArgs($instances);
}
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末揩慕,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子拴鸵,更是在濱河造成了極大的恐慌蜗搔,老刑警劉巖,帶你破解...
    沈念sama閱讀 217,406評(píng)論 6 503
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件聘芜,死亡現(xiàn)場(chǎng)離奇詭異缝龄,居然都是意外死亡,警方通過(guò)查閱死者的電腦和手機(jī)二拐,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,732評(píng)論 3 393
  • 文/潘曉璐 我一進(jìn)店門百新,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái),“玉大人饭望,你說(shuō)我怎么就攤上這事⊙崞” “怎么了?”我有些...
    開(kāi)封第一講書(shū)人閱讀 163,711評(píng)論 0 353
  • 文/不壞的土叔 我叫張陵富纸,是天一觀的道長(zhǎng)旨椒。 經(jīng)常有香客問(wèn)我,道長(zhǎng)涣仿,這世上最難降的妖魔是什么示惊? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 58,380評(píng)論 1 293
  • 正文 為了忘掉前任,我火速辦了婚禮钧汹,結(jié)果婚禮上阔拳,老公的妹妹穿的比我還像新娘类嗤。我一直安慰自己,他們只是感情好遗锣,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,432評(píng)論 6 392
  • 文/花漫 我一把揭開(kāi)白布精偿。 她就那樣靜靜地躺著,像睡著了一般笔咽。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上拯田,一...
    開(kāi)封第一講書(shū)人閱讀 51,301評(píng)論 1 301
  • 那天船庇,我揣著相機(jī)與錄音,去河邊找鬼鸭轮。 笑死,一個(gè)胖子當(dāng)著我的面吹牛邑蒋,可吹牛的內(nèi)容都是我干的按厘。 我是一名探鬼主播,決...
    沈念sama閱讀 40,145評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼遮咖,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼造虏!你這毒婦竟也來(lái)了?” 一聲冷哼從身側(cè)響起漓藕,我...
    開(kāi)封第一講書(shū)人閱讀 39,008評(píng)論 0 276
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤享钞,失蹤者是張志新(化名)和其女友劉穎,沒(méi)想到半個(gè)月后暑脆,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體狐肢,經(jīng)...
    沈念sama閱讀 45,443評(píng)論 1 314
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,649評(píng)論 3 334
  • 正文 我和宋清朗相戀三年碟联,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了僵腺。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 39,795評(píng)論 1 347
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡普监,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出锡移,到底是詐尸還是另有隱情漆际,我是刑警寧澤,帶...
    沈念sama閱讀 35,501評(píng)論 5 345
  • 正文 年R本政府宣布施符,位于F島的核電站擂找,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏贯涎。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,119評(píng)論 3 328
  • 文/蒙蒙 一陆盘、第九天 我趴在偏房一處隱蔽的房頂上張望败明。 院中可真熱鬧,春花似錦酸员、人聲如沸讳嘱。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 31,731評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)叛氨。三九已至,卻和暖如春寞埠,著一層夾襖步出監(jiān)牢的瞬間焊夸,已是汗流浹背。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 32,865評(píng)論 1 269
  • 我被黑心中介騙來(lái)泰國(guó)打工饭冬, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人昌抠。 一個(gè)月前我還...
    沈念sama閱讀 47,899評(píng)論 2 370
  • 正文 我出身青樓炊苫,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親侨艾。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,724評(píng)論 2 354

推薦閱讀更多精彩內(nèi)容