【lara】IoC 模式 - 服務(wù)容器

服務(wù)容器工作示意圖

$bindings用于存儲(chǔ)提供服務(wù)的回調(diào)函數(shù)
$instances用于存儲(chǔ)程序中共享的實(shí)例意狠,也可以稱為單例。

服務(wù)容器的生成

bootstrap/app.php 文件實(shí)現(xiàn)了服務(wù)容器的實(shí)例化典阵,同時(shí)綁定了核心處理類。至此,已經(jīng)獲得了一個(gè)全局的服務(wù)容器實(shí)例酝静,即$app辩棒。

Register an existing instance as shared in the container
綁定當(dāng)前 Application 對(duì)象進(jìn)容器狼忱,綁定的是同一對(duì)象,但給了兩個(gè)名字
$this->registerBaseBindings();
  app
  Illuminate\Container\Container

$this->registerBaseServiceProviders();
   $this->register(new EventServiceProvider($this));
   $this->register(new LogServiceProvider($this));
   $this->register(new RoutingServiceProvider($this));


注冊(cè)別名
$this->registerCoreContainerAliases();

服務(wù)綁定

綁定實(shí)際上可以簡(jiǎn)單地理解為一個(gè)關(guān)鍵字和一個(gè)服務(wù)進(jìn)行綁定一睁,可以簡(jiǎn)單看做是一種鍵值對(duì)形式钻弄,即一個(gè)“key”對(duì)應(yīng)一個(gè)服務(wù)。對(duì)于綁定服務(wù)的不同者吁,需要服務(wù)容器中不同的綁定函數(shù)來實(shí)現(xiàn)窘俺,主要包括回調(diào)函數(shù)服務(wù)綁定和實(shí)例對(duì)象服務(wù)綁定。

  • 普通綁定
    普通綁定每次生成該服務(wù)的實(shí)例對(duì)象時(shí)都會(huì)生成一個(gè)新的實(shí)例對(duì)象复凳,也就是說在程序的生命周期中瘤泪,可以同時(shí)生成很多個(gè)這種實(shí)例對(duì)象。
  • 單例綁定
    單例綁定在生成一個(gè)實(shí)例對(duì)象后育八,如果再次生成就會(huì)返回第一次生成的實(shí)例對(duì)象对途,也就是說在程序的生命周期中,只能生成一個(gè)這樣的實(shí)例對(duì)象髓棋,如果想使用就會(huì)獲取之前生成的掀宋,也就是設(shè)計(jì)模式中的單例模式。

回調(diào)函數(shù)服務(wù)綁定的就是一個(gè)回調(diào)函數(shù)

實(shí)例對(duì)象服務(wù)綁定的是一個(gè)實(shí)例對(duì)象

服務(wù)解析

當(dāng)服務(wù)已經(jīng)綁定到服務(wù)容器中后仲锄,就可以在之后的時(shí)間隨時(shí)獲取劲妙,也可以稱為服務(wù)解析。
服務(wù)解析需要兩個(gè)步驟

  • 一個(gè)是獲取服務(wù)容器對(duì)象儒喊,在Laravel框架中因?yàn)樗械墓δ苣K都是通過服務(wù)容器實(shí)例黏合在一起镣奋,所以大部分功能類中都記錄服務(wù)容器實(shí)例的屬性,通常為$app屬性怀愧,也可以通過Facades中的App外觀或app()全局函數(shù)來獲惹染薄余赢;
  • 另一個(gè)是通過服務(wù)容器實(shí)現(xiàn)對(duì)應(yīng)服務(wù)的解析。

singleton()函數(shù)實(shí)現(xiàn)的是單例綁定哈垢,即程序中如果沒有服務(wù)名稱對(duì)應(yīng)的實(shí)例對(duì)象妻柒,則通過服務(wù)容器實(shí)例化一個(gè)后并進(jìn)行記錄,如果在后續(xù)程序中還需要同名的服務(wù)時(shí)則返回先前創(chuàng)建的服務(wù)實(shí)例對(duì)象耘分。該函數(shù)相當(dāng)于bind()函數(shù)的一個(gè)特例举塔,即參數(shù)$shared值為true的情況。對(duì)于bind()函數(shù)實(shí)現(xiàn)的服務(wù)綁定功能求泰,在忽略$shared參數(shù)的情況下央渣,即不討論單例還是普通的服務(wù),可以分為兩種情況渴频,
如果參數(shù)$concrete為一個(gè)回調(diào)函數(shù)芽丹,則直接將回調(diào)函數(shù)與服務(wù)名稱$abstract進(jìn)行綁定;
如果參數(shù)$concrete為一個(gè)名稱卜朗,則首先需要通過getClosure()函數(shù)創(chuàng)建服務(wù)回調(diào)函數(shù)拔第,然后將該回調(diào)函數(shù)與服務(wù)名稱綁定,總之需要實(shí)現(xiàn)一個(gè)可以生成相應(yīng)服務(wù)實(shí)例對(duì)象的回調(diào)函數(shù)與服務(wù)名稱進(jìn)行綁定场钉。

首先介紹服務(wù)查找過程蚊俺,即由make()函數(shù)實(shí)現(xiàn)的功能。該函數(shù)需要提供兩個(gè)參數(shù)惹悄,分別是$abstract和$parameters春叫,
$abstract可以看做是服務(wù)名稱肩钠,
$parameters是創(chuàng)建實(shí)例化對(duì)象需要的參數(shù)泣港,即一個(gè)類實(shí)例化時(shí)的依賴。

對(duì)于服務(wù)的查找是根據(jù)服務(wù)名稱$abstract來進(jìn)行的:

  • 首先通過getAlias()函數(shù)來查找服務(wù)名稱是否有別名价匠,對(duì)于服務(wù)別名的管理是通過服getAlias()函數(shù)來查找服務(wù)名稱是否有別名当纱,對(duì)于服務(wù)別名的管理是通過服務(wù)容器類中的$aliases數(shù)組屬性實(shí)現(xiàn)的,而內(nèi)容基本是通過Illuminate\Foundation\Application類中的registerCoreContainerAliases()函數(shù)注冊(cè)的踩窖,如一個(gè)簡(jiǎn)單的實(shí)例坡氯,Illuminate\Contracts\Container\Container抽象類的別名為“app”,如果查找到了別名洋腮,將查找該別名對(duì)應(yīng)的服務(wù)箫柳,如果該抽象類沒有別名,則繼續(xù)進(jìn)行查找啥供。

  • 然后在服務(wù)容器的共享實(shí)例數(shù)組($instances屬性)中查找服務(wù)名稱的實(shí)例悯恍,如果查找到則說明該服務(wù)名稱對(duì)應(yīng)為單例,直接返回先前實(shí)例化的對(duì)象伙狐,否則繼續(xù)查詢涮毫。

  • 接下來瞬欧,會(huì)通過getConcrete()獲取服務(wù)名稱的實(shí)體,在服務(wù)綁定時(shí)罢防,一個(gè)服務(wù)名稱一般綁定一個(gè)回調(diào)函數(shù)用于生成實(shí)例對(duì)象艘虎,而這個(gè)回調(diào)函數(shù)就相當(dāng)于服務(wù)名稱的實(shí)體。這個(gè)實(shí)體的查找就是通過容器中的$bindings數(shù)組屬性實(shí)現(xiàn)的咒吐,如果查找到則返回實(shí)體野建,否則修改服務(wù)名稱的形式繼續(xù)下一次的查找。

  • 然后渤滞,會(huì)通過isBuildable()函數(shù)判斷服務(wù)實(shí)體能否創(chuàng)建實(shí)例化對(duì)象贬墩,如果可以則轉(zhuǎn)到下一個(gè)步驟,否則繼續(xù)通過make()函數(shù)來查找妄呕。

  • 在完成實(shí)例對(duì)象的創(chuàng)建后陶舞,通過isShared()判斷該服務(wù)是否為單例,如果是需要在共享實(shí)例對(duì)象數(shù)組($instances)中記錄绪励。

在通過make()函數(shù)查找到服務(wù)實(shí)體后肿孵,會(huì)將其傳遞給build()函數(shù)用于對(duì)象的創(chuàng)建

  • 如果服務(wù)實(shí)體就是一個(gè)閉包函數(shù),則直接調(diào)用該閉包函數(shù)完成服務(wù)實(shí)例化對(duì)象的創(chuàng)建
  • 如果服務(wù)實(shí)體只是一個(gè)具體類的類名疏魏,則需要通過反射機(jī)制來完成實(shí)例化對(duì)象的創(chuàng)建停做。
    通過反射機(jī)制完成對(duì)象實(shí)例化的過程,首先是根據(jù)將要實(shí)例化的類名稱獲取反射類(ReflectionClass)實(shí)例大莫,然后獲取該類在實(shí)例化過程中的依賴蛉腌,即構(gòu)造函數(shù)需要的參數(shù),在build()函數(shù)中只厘,通過getDependencies()函數(shù)來實(shí)現(xiàn)依賴的生成烙丛,如果在服務(wù)解析時(shí)提供了相應(yīng)的參數(shù),即通過$parameters參數(shù)提供羔味,則直接使用提供的參數(shù)河咽,如果沒有提供,則通過服務(wù)容器中的resolveNonClass()函數(shù)來獲取默認(rèn)參數(shù)赋元,或者通過resolveClass()函數(shù)來創(chuàng)建忘蟹,而創(chuàng)建的方式也是通過服務(wù)容器,所以服務(wù)容器解決依賴注入的問題就是通過這部分代碼實(shí)現(xiàn)的搁凸。在解決了依賴的問題后媚值,可以直接通過反射機(jī)制完成服務(wù)實(shí)例對(duì)象的創(chuàng)建。

bind

綁定接口和生成相應(yīng)的回調(diào)函數(shù)
如果參數(shù) $concrete 為一個(gè)回調(diào)函數(shù)护糖,則直接將回調(diào)函數(shù)與服務(wù)名稱$abstract 進(jìn)行綁定
如果參數(shù) $concrete 為一個(gè)名稱褥芒,則首先需要通過 getClosure() 函數(shù)創(chuàng)建服務(wù)回調(diào)函數(shù),然后將回調(diào)函數(shù)與服務(wù)名稱綁定椅文,總之需要實(shí)現(xiàn)一個(gè)可以生成相應(yīng)服務(wù)實(shí)例對(duì)象的回調(diào)函數(shù)與服務(wù)名稱進(jìn)行綁定喂很。

make 服務(wù)解析

解析順序

  • getAlias() 別名
  • $instances 共享實(shí)例
  • getConcrete( $abstract ) 獲取服務(wù)名稱實(shí)體
  • 找到實(shí)體后惜颇,如果是回調(diào)函數(shù)直接返回; 如果是類名則通過反射機(jī)制生成實(shí)例對(duì)象

abstract 服務(wù)名稱
concrete 服務(wù)名稱的實(shí)體 (對(duì)象 or 回調(diào)函數(shù))

可以將其分為兩個(gè)步驟來完成:

  • 一個(gè)是完成對(duì)應(yīng)服務(wù)的查找
  • 另一個(gè)是完成服務(wù)的實(shí)現(xiàn)少辣,一般是指完成實(shí)例化對(duì)象的創(chuàng)建凌摄。

兩個(gè)步驟分別由make() 和 build() 函數(shù)完成。
首先介紹服務(wù)查找過程漓帅,即由 make() 函數(shù)實(shí)現(xiàn)的功能锨亏。該函數(shù)需要提供兩個(gè)參數(shù),分別是 $abstract 和 $parameters, $abstract 可以看做是服務(wù)名稱忙干,而 $parameters 是創(chuàng)建實(shí)例化對(duì)象需要的參數(shù)器予,即一個(gè)類實(shí)例化時(shí)的依賴。

對(duì)于服務(wù)的查找是根據(jù)服務(wù)名稱 $abstract 來進(jìn)行的捐迫,首先通過 getAlias() 函數(shù)來查找服務(wù)名稱是否有別名乾翔,對(duì)于服務(wù)別名的管理是通過服務(wù)容器類的 $alias 數(shù)組屬性實(shí)現(xiàn)的,而內(nèi)容基本是通過 Illuminate\Foundation\Application 類中的 registerCoreContainerAliases() 函數(shù)注冊(cè)的施戴,如一個(gè)簡(jiǎn)單的實(shí)例反浓, Illuminate\Contracts\Container\Container 抽象類的別名為 "app",如果查到了別名赞哗,將查找該別名對(duì)應(yīng)的服務(wù)雷则,如果該抽象類沒有別名,則繼續(xù)進(jìn)行查找肪笋。然后在服務(wù)容器的共享實(shí)例數(shù)組( $instances 屬性) 中查找服務(wù)名稱的實(shí)例月劈,如果查找到則說明該服務(wù)名稱對(duì)應(yīng)為單例,直接返回先前實(shí)例化的對(duì)象藤乙,否則繼續(xù)查詢猜揪。

接下來,通過 getConcrete() 獲取服務(wù)名稱的實(shí)體湾盒,在服務(wù)綁定時(shí)湿右,一個(gè)服務(wù)名稱一般綁定一個(gè)回調(diào)函數(shù)用于生成實(shí)例對(duì)象诅妹,而這個(gè)回調(diào)函數(shù)就相當(dāng)于服務(wù)名稱的實(shí)體罚勾。這個(gè)實(shí)體的查找就是通過容器中的 $bindings 數(shù)組屬性實(shí)現(xiàn)的,如果查找到則返回實(shí)體吭狡,否則修改服務(wù)名稱的形式繼續(xù)下一次的查找尖殃。然后通過 isBuildable() 函數(shù)判斷服務(wù)實(shí)體能否創(chuàng)建實(shí)例化對(duì)象,如果可以則轉(zhuǎn)到下一個(gè)步驟划煮,否則繼續(xù)轉(zhuǎn)到make() 函數(shù)來查找送丰。在完成實(shí)例化對(duì)象的創(chuàng)建后,通過 isShared() 判斷該服務(wù)是否為單例弛秋,如果是需要在共享實(shí)例函數(shù)組 ($instances) 中記錄器躏。

在通過 make() 函數(shù)查找到服務(wù)實(shí)體后俐载,會(huì)將其傳遞給 build() 函數(shù)用于對(duì)象的創(chuàng)建,如果服務(wù)實(shí)體就是一個(gè)閉包函數(shù)登失,則直接調(diào)用該閉包函數(shù)完成服務(wù)實(shí)例化對(duì)象的創(chuàng)建遏佣,如果服務(wù)實(shí)體只是一個(gè)具體類的類名,則需要通過反射機(jī)制來完成實(shí)例化對(duì)象的創(chuàng)建揽浙。通過反射機(jī)制完成對(duì)象實(shí)例化的過程状婶,首先是根據(jù)將要實(shí)例化的類名稱獲取反射類(ReflectionClass)實(shí)例,然后獲取該類在實(shí)例化過程中的依賴馅巷,即構(gòu)造函數(shù)需要的參數(shù)膛虫,在 build() 函數(shù)中,通過getDependencies() 函數(shù)來實(shí)現(xiàn)依賴的生成钓猬,如果在服務(wù)解析時(shí)提供了相應(yīng)的參數(shù)稍刀,即通過 $parameters 參數(shù)提供,則直接使用提供的參數(shù)敞曹,如果沒有提供掉丽,則通過服務(wù)容器中的 resoleveNonClass() 函數(shù)來獲取默認(rèn)參數(shù),或者通過 resolveClass() 函數(shù)來創(chuàng)建异雁,而創(chuàng)建的方式也是通過服務(wù)容器捶障,所以服務(wù)容器解決依賴注入的問題就是通過這部分代碼實(shí)現(xiàn)的。在解決了依賴的問題后纲刀,可以直接通過反射機(jī)制完成服務(wù)實(shí)例對(duì)象的創(chuàng)建项炼。

build

反射機(jī)制實(shí)例化類

$reflector = new ReflectionClass( $concrete );
$constructor = $reflector->getConstructor();
$dependencies = $constructor->getDepencies();


# 解決通過反射機(jī)制實(shí)例化類時(shí)的依賴
$instances = $this->getDependencies( $dependencies );
return $reflector->newInstanceArgs( $instances );
  • 反射機(jī)制是指在PHP運(yùn)行狀態(tài)中,擴(kuò)展分析PHP程序示绊,導(dǎo)出或提取出關(guān)于類锭部、方法、屬性面褐、參數(shù)等的詳細(xì)信息拌禾,包括注釋。這種動(dòng)態(tài)獲取的信息以及動(dòng)態(tài)調(diào)用對(duì)象的方法的功能稱為反射API展哭。
  • 反射是操縱面向?qū)ο蠓缎椭性P偷腁PI湃窍,其功能十分強(qiáng)大,可幫助我們構(gòu)建復(fù)雜匪傍,可擴(kuò)展的應(yīng)用您市。 其用途如:自動(dòng)加載插件,自動(dòng)生成文檔役衡,甚至可用來擴(kuò)充PHP語言茵休。

實(shí)例化對(duì)象(對(duì)象的創(chuàng)建)
如果服務(wù)實(shí)體就是一個(gè)閉包函數(shù),則直接調(diào)用該閉包函數(shù)完成服務(wù)實(shí)例化對(duì)象的創(chuàng)建
如果服務(wù)實(shí)體只是一個(gè)具體類的類名,則需要通過反射機(jī)制來完成實(shí)例化對(duì)象的創(chuàng)建榕莺。

在解決了依賴的問題后俐芯,可以直接通過反射機(jī)制完成服務(wù)實(shí)例對(duì)象的創(chuàng)建。

<?php

//設(shè)計(jì)容器類, 容器類裝實(shí)例或提供實(shí)例的回調(diào)函數(shù)
class Container
{
  //用于裝提供實(shí)例的回調(diào)函數(shù), 真正的容器還會(huì)裝實(shí)例等其他內(nèi)容
  //從而實(shí)現(xiàn)單例等高級(jí)功能
  protected $bindings = [];
  //綁定接口和生成相應(yīng)實(shí)例的回調(diào)函數(shù)
  public function bind($abstract, $concrete = null, $shared = false)
  {
    if ( ! $concrete instanceof Closure){
    //如果提供的參數(shù)不是回調(diào)函數(shù), 則產(chǎn)生默認(rèn)的回調(diào)函數(shù)
      $concrete = $this->getClosure($abstract, $concrete);
    }
    $this->bindings[$abstract] = compact('concrete', 'shared');
  }
  
  //默認(rèn)生成實(shí)例的回調(diào)函數(shù)
  protected function getClosure($abstract, $concrete)
  {
    //生成實(shí)例的回調(diào)函數(shù), $c一般為IoC容器對(duì)象, 在調(diào)用回調(diào)生成實(shí)例時(shí)提供
    //即build函數(shù)中的 $concrete($this)
    return function($c) use ($abstract, $concrete)
    {
      $method = ($abstract == $concrete) ? 'build' : 'make';
  
      //調(diào)用的是容器的build或make方法生成實(shí)例
      return $c->$method($concrete);
    };
  }

  //生成實(shí)例對(duì)象, 首先解決接口和要實(shí)例化類之間的依賴關(guān)系
  public function make($abstract)
  {
    $concrete = $this->getConcrete($abstract);
    
    if ($this->isBuildable($concrete, $abstract)) {
      $object = $this->build($concrete);
    }
    else
    {
      $object = $this->make($concrete);
    }

    return $object;
  }
  
  protected function isBuildable($concrete, $abstract)
  {
    return $concrete === $abstract || $concrete instanceof Closure;
  }

  //獲取綁定的回調(diào)函數(shù)
  protected function getConcrete($abstract)
  {
    if ( ! isset($this->bindings[$abstract]))
    {       
      return $abstract;
    }

    return $this->bindings[$abstract]['concrete'];
  }

  //實(shí)例化對(duì)象
  public function build($concrete)
  {
    if ($concrete instanceof Closure){
      return $concrete($this);
    }

    $reflector = new ReflectionClass($concrete);

    if ( ! $reflector->isInstantiable())
    {
      echo $message = "Target [$concrete] is not instantiable.";
    }

    $constructor = $reflector->getConstructor();

    if (is_null($constructor))
    {
      return new $concrete;
    }

    $dependencies = $constructor->getParameters();
    $instances = $this->getDependencies($dependencies);

    return $reflector->newInstanceArgs($instances);
  }

  //解決通過反射機(jī)制實(shí)例化對(duì)象時(shí)的依賴
  protected function getDependencies($parameters)
  {
    $dependencies = [];
    foreach ($parameters as $parameter)
    {
      $dependency = $parameter->getClass();
      if (is_null($dependency))
      {
        $dependencies[] = NULL;
      }
      else
      {
        $dependencies[] = $this->resolveClass($parameter);
      }
    }

    return (array) $dependencies;
  }

  protected function resolveClass(ReflectionParameter $parameter)
  {
    return $this->make($parameter->getClass()->name);
  }
}

class Traveller
{
  protected $tool;
  
  public function __construct(Visit $tool)
  {
    $this->tool = $tool;
  }
  
  public function visitTibet()
  {
    $this->tool->go();
  }
}

interface Visit
{
  public function go();
}

class Train implements Visit
{
  public function go()
  {
    echo "train. <br>";
  }
}
$app = new Container();
$app->bind("Visit", "Train");
$app->bind("traveller", "Traveller");

$tra = $app->make("traveller");
$tra->visitTibet();

Laravel學(xué)習(xí)筆記之IoC Container實(shí)例化源碼解析

PHP 反射機(jī)制Reflection

Inversion of Control – The Hollywood Principle

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末钉鸯,一起剝皮案震驚了整個(gè)濱河市泼各,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌亏拉,老刑警劉巖扣蜻,帶你破解...
    沈念sama閱讀 222,183評(píng)論 6 516
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異及塘,居然都是意外死亡莽使,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,850評(píng)論 3 399
  • 文/潘曉璐 我一進(jìn)店門笙僚,熙熙樓的掌柜王于貴愁眉苦臉地迎上來芳肌,“玉大人,你說我怎么就攤上這事肋层∫隗裕” “怎么了?”我有些...
    開封第一講書人閱讀 168,766評(píng)論 0 361
  • 文/不壞的土叔 我叫張陵栋猖,是天一觀的道長(zhǎng)净薛。 經(jīng)常有香客問我,道長(zhǎng)蒲拉,這世上最難降的妖魔是什么肃拜? 我笑而不...
    開封第一講書人閱讀 59,854評(píng)論 1 299
  • 正文 為了忘掉前任,我火速辦了婚禮雌团,結(jié)果婚禮上燃领,老公的妹妹穿的比我還像新娘。我一直安慰自己锦援,他們只是感情好猛蔽,可當(dāng)我...
    茶點(diǎn)故事閱讀 68,871評(píng)論 6 398
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著灵寺,像睡著了一般曼库。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上替久,一...
    開封第一講書人閱讀 52,457評(píng)論 1 311
  • 那天凉泄,我揣著相機(jī)與錄音躏尉,去河邊找鬼蚯根。 笑死,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的颅拦。 我是一名探鬼主播蒂誉,決...
    沈念sama閱讀 40,999評(píng)論 3 422
  • 文/蒼蘭香墨 我猛地睜開眼,長(zhǎng)吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼距帅!你這毒婦竟也來了右锨?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 39,914評(píng)論 0 277
  • 序言:老撾萬榮一對(duì)情侶失蹤碌秸,失蹤者是張志新(化名)和其女友劉穎绍移,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體讥电,經(jīng)...
    沈念sama閱讀 46,465評(píng)論 1 319
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡蹂窖,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 38,543評(píng)論 3 342
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了恩敌。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片瞬测。...
    茶點(diǎn)故事閱讀 40,675評(píng)論 1 353
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖纠炮,靈堂內(nèi)的尸體忽然破棺而出月趟,到底是詐尸還是另有隱情,我是刑警寧澤恢口,帶...
    沈念sama閱讀 36,354評(píng)論 5 351
  • 正文 年R本政府宣布孝宗,位于F島的核電站,受9級(jí)特大地震影響耕肩,放射性物質(zhì)發(fā)生泄漏碳褒。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 42,029評(píng)論 3 335
  • 文/蒙蒙 一看疗、第九天 我趴在偏房一處隱蔽的房頂上張望沙峻。 院中可真熱鬧,春花似錦两芳、人聲如沸摔寨。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,514評(píng)論 0 25
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽是复。三九已至,卻和暖如春竖螃,著一層夾襖步出監(jiān)牢的瞬間淑廊,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,616評(píng)論 1 274
  • 我被黑心中介騙來泰國(guó)打工特咆, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留季惩,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 49,091評(píng)論 3 378
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像画拾,于是被迫代替她去往敵國(guó)和親啥繁。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,685評(píng)論 2 360

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

  • 2.1 我們的理念是:讓別人為你服務(wù) IoC是隨著近年來輕量級(jí)容器(Lightweight Container)的...
    好好學(xué)習(xí)Sun閱讀 2,716評(píng)論 0 11
  • http://liuxing.info/2017/06/30/Spring%20AMQP%E4%B8%AD%E6%...
    sherlock_6981閱讀 15,941評(píng)論 2 11
  • 本文面向php語言的laravel框架的用戶青抛,介紹一些laravel框架里面容器管理方面的使用要點(diǎn)旗闽。文章很長(zhǎng),但是...
    spacexxxx閱讀 1,164評(píng)論 0 1
  • 1.JQuery 基礎(chǔ) 改變web開發(fā)人員創(chuàng)造搞交互性界面的方式蜜另。設(shè)計(jì)者無需花費(fèi)時(shí)間糾纏JS復(fù)雜的高級(jí)特性适室。 1....
    LaBaby_閱讀 1,347評(píng)論 0 2
  • 服務(wù)容器 容器 通俗的理解就是裝東西的物體,常見的一個(gè)變量举瑰、一個(gè)對(duì)象等都可以看成一個(gè)容器亭病,而服務(wù)容器就是提供服務(wù)的...
    邱杉的博客閱讀 609評(píng)論 0 51