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

前言

經(jīng)過對依賴注入疏旨、控制反轉(zhuǎn)识椰、服務(wù)容器醇坝、服務(wù)提供者的了解后,對服務(wù)容器等有了初步的概念胧卤,可以簡單的將服務(wù)容器理解為一個在框架啟動時通過綁定的方式收納服務(wù)的一個數(shù)組武翎。這里就將服務(wù)容器的操作分為綁定篇及解析篇來進行記錄蛉腌。

正文

在Laravel的服務(wù)容器中提供了三種用于綁定的方法拓瞪,以及兩個用于存儲服務(wù)綁定關(guān)系的成員變量
instance方法會將綁定關(guān)系存在instances中
bind和singleton則將綁定關(guān)系存在bindings中

instance

將現(xiàn)有實例注冊到容器中缴罗,簡單說就是直接綁定已有的實例

//調(diào)用范例
$this->instance('app', $this);

public function instance($abstract, $instance)
{
    //移除之前注冊過的別名
    $this->removeAbstractAlias($abstract);

    //獲取是否有過綁定,主要是對成員變量bindings祭埂,instances面氓,aliases進行isset判斷
    $isBound = $this->bound($abstract);

    //移除標示對應(yīng)的別名
    unset($this->aliases[$abstract]);

    //以傳入的$abstract為鍵,實例$instance為值存入成員變量instances中  
    $this->instances[$abstract] = $instance;

    //判斷未經(jīng)過綁定
    if ($isBound) {
        //rebound主要做的是獲取當前標示($abstract)配置的回調(diào)進行執(zhí)行
        $this->rebound($abstract);
    }

    return $instance;
}
protected function rebound($abstract)
{
    //解析出實例蛆橡,具體解析會再后面的解析篇進行解讀
    $instance = $this->make($abstract);

    //獲取成員變量reboundCallbacks中是否存在為當前標示($abstract)配置的回調(diào)
    //有的話則進行調(diào)用
    //這里的回調(diào)一般都是在服務(wù)提供者內(nèi)部調(diào)用容器的rebinding方法進行配置的
    foreach ($this->getReboundCallbacks($abstract) as $callback) {
        call_user_func($callback, $this, $instance);
    }
}

bind

向容器注冊綁定舌界,一般會以閉包的形式進行綁定,也有的會以命名空間+類名的形式進行綁定泰演,再bind方法內(nèi)部再通過命名空間+類名生成閉包

//調(diào)用范例
$this->bind('redis', function(){
   return new Redis();
});
public function bind($abstract, $concrete = null, $shared = false)
{
    //刪除所有舊的實例和別名
    $this->dropStaleInstances($abstract);

    if (is_null($concrete)) {
        $concrete = $abstract;
    }

    //如果$concrete傳的不是閉包呻拌,則在這里為其生成concrete閉包
    if (! $concrete instanceof Closure) {
        $concrete = $this->getClosure($abstract, $concrete);
    }

    //以 $abstract 為鍵,$concrete 和 $shared 合并成的數(shù)組為值睦焕, 賦值到 bindings 屬性中
    $this->bindings[$abstract] = compact('concrete', 'shared');

    //判斷 $abstract 標示是否存在與成員變量instances(通過instance進行綁定)
    //和resolved(當被解析過后resolved中會存$abstract => true)中
    //簡單說就是滿足上面其中之一后就說明這個綁定的實例已經(jīng)經(jīng)過實例化了
    if ($this->resolved($abstract)) {
        //rebound主要做的是獲取當前標示($abstract)配置的回調(diào)進行執(zhí)行
        $this->rebound($abstract);
    }
}
//獲取閉包
protected function getClosure($abstract, $concrete)
{
    //閉包內(nèi)的代碼只有調(diào)用是才會執(zhí)行
    return function ($container, $parameters = []) use ($abstract, $concrete) {
        //值相同的時候通過反射類進行實例獲取
        if ($abstract == $concrete) {
            return $container->build($concrete);
        }
        //如果不相同則會根據(jù)$concrete再次進行解析
        return $container->resolve(
            $concrete, $parameters, $raiseEvents = false
        );
    };
}

singleton

在容器中注冊共享綁定
該方法其實就是在內(nèi)部調(diào)用了bind藐握,再調(diào)用時將第三個參數(shù)寫死為true,以單例的方式進行綁定

//調(diào)用范例
$this->singleton('redis', function(){
   return new Redis();
});
public function singleton($abstract, $concrete = null)
{
    $this->bind($abstract, $concrete, true);
}

END

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末垃喊,一起剝皮案震驚了整個濱河市猾普,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌本谜,老刑警劉巖初家,帶你破解...
    沈念sama閱讀 217,406評論 6 503
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異乌助,居然都是意外死亡溜在,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,732評論 3 393
  • 文/潘曉璐 我一進店門他托,熙熙樓的掌柜王于貴愁眉苦臉地迎上來炕泳,“玉大人,你說我怎么就攤上這事上祈∨嘧瘢” “怎么了?”我有些...
    開封第一講書人閱讀 163,711評論 0 353
  • 文/不壞的土叔 我叫張陵登刺,是天一觀的道長籽腕。 經(jīng)常有香客問我,道長纸俭,這世上最難降的妖魔是什么皇耗? 我笑而不...
    開封第一講書人閱讀 58,380評論 1 293
  • 正文 為了忘掉前任,我火速辦了婚禮揍很,結(jié)果婚禮上郎楼,老公的妹妹穿的比我還像新娘万伤。我一直安慰自己,他們只是感情好呜袁,可當我...
    茶點故事閱讀 67,432評論 6 392
  • 文/花漫 我一把揭開白布敌买。 她就那樣靜靜地躺著,像睡著了一般阶界。 火紅的嫁衣襯著肌膚如雪虹钮。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,301評論 1 301
  • 那天膘融,我揣著相機與錄音芙粱,去河邊找鬼。 笑死氧映,一個胖子當著我的面吹牛春畔,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播岛都,決...
    沈念sama閱讀 40,145評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼拐迁,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了疗绣?” 一聲冷哼從身側(cè)響起线召,我...
    開封第一講書人閱讀 39,008評論 0 276
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎多矮,沒想到半個月后缓淹,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,443評論 1 314
  • 正文 獨居荒郊野嶺守林人離奇死亡塔逃,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,649評論 3 334
  • 正文 我和宋清朗相戀三年讯壶,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片湾盗。...
    茶點故事閱讀 39,795評論 1 347
  • 序言:一個原本活蹦亂跳的男人離奇死亡伏蚊,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出格粪,到底是詐尸還是另有隱情躏吊,我是刑警寧澤,帶...
    沈念sama閱讀 35,501評論 5 345
  • 正文 年R本政府宣布帐萎,位于F島的核電站比伏,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏疆导。R本人自食惡果不足惜赁项,卻給世界環(huán)境...
    茶點故事閱讀 41,119評論 3 328
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧悠菜,春花似錦舰攒、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,731評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至篙顺,卻和暖如春偶芍,著一層夾襖步出監(jiān)牢的瞬間充择,已是汗流浹背德玫。 一陣腳步聲響...
    開封第一講書人閱讀 32,865評論 1 269
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留椎麦,地道東北人宰僧。 一個月前我還...
    沈念sama閱讀 47,899評論 2 370
  • 正文 我出身青樓,卻偏偏與公主長得像观挎,于是被迫代替她去往敵國和親琴儿。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 44,724評論 2 354

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