laravel 源码分析index make方法解析

摘抄自 :http://www.mamicode.com/info-detail-2231705.html](http://www.mamicode.com/info-detail-2231705.html

在laravel源码中index.php中,引入

$app = require_once __DIR__.'/../bootstrap/app.php';

$kernel = $app->make(Illuminate\Contracts\Http\Kernel::class);

其中这个make方法是从容器中解析一个实例 type return;其中Illuminate\Foundation\Application这个类和它的父类Illuminate\Container\Container类中都有make方法,
当执行index.php的时候,就会首先去执行Illuminate\Foundation\Application中的make方法

 /**
 2      * Resolve the given type from the container. 从容器当中解析给定的type
 3      *
 4      * (Overriding Container::make) 覆盖了父类中的make方法
 5      *
 6      * @param  string  $abstract 给定的type
 7      * @param  array  $parameters 指定一些参数 可选项
 8      * @return mixed
 9      */
10     public function make($abstract, array $parameters = [])
11     {
12         $abstract = $this->getAlias($abstract);//调用父类中的getAlias方法
13      //如果在deferredServices这个数组设置了这个type并且在instances数组中没有设置这个type
14         if (isset($this->deferredServices[$abstract]) && ! isset($this->instances[$abstract])) {
15             $this->loadDeferredProvider($abstract);//那么就执行这个方法:加载被定义为延迟的服务提供者
16         }
17 
18         return parent::make($abstract, $parameters);//调用父类的make方法
19     }

好,我们一步一步的来,先看看这个getAlias方法,这个方法的作用就是返回这个类的别名,如果给出的是一个完整的类名且在aliases中已经设置了那么就返回这个类名的别名,如果没有设置过就返回这个类名本身,大家在看这个方法的时候可以先var_dump一下$app,对照着看里面的aliases数组,框架作者写这个方法真的很巧妙,至少这种递归方式在我实际开发当中很少用到。

/**
 2      * Get the alias for an abstract if available.
 3      *
 4      * @param  string  $abstract
 5      * @return string
 6      *
 7      * @throws \LogicException
 8      */
 9     public function getAlias($abstract)
10     {
11         if (! isset($this->aliases[$abstract])) {
12             return $abstract;
13         }
14 
15         if ($this->aliases[$abstract] === $abstract) {
16             throw new LogicException("[{$abstract}] is aliased to itself.");
17         }
18 
19         return $this->getAlias($this->aliases[$abstract]);
20     }

接下来就是对deferredServices和instances这个两个数组进行判断,在本例 app->make(Illuminate\Contracts\Http\Kernel::class); 当中,判断的结果为false,因此不执行loadDeferredProvider方法。
再接下来就是调用父类Illuminate\Container\Container中的make方法了


/**
     * Resolve the given type from the container.
     *
     * @param  string  $abstract
     * @param  array  $parameters
     * @return mixed
     *
     * @throws \Illuminate\Contracts\Container\BindingResolutionException
     */
    public function make($abstract, array $parameters = [])
    {
        return $this->resolve($abstract, $parameters);
    }

重点来了,我们看看这个resolve方法执行了哪些操作,

 /**
     * Resolve the given type from the container.
     *
     * @param  string  $abstract
     * @param  array  $parameters
     * @param  bool   $raiseEvents
     * @return mixed
     *
     * @throws \Illuminate\Contracts\Container\BindingResolutionException
     */
    protected function resolve($abstract, $parameters = [], $raiseEvents = true)
    {
        $abstract = $this->getAlias($abstract);

        $needsContextualBuild = ! empty($parameters) || ! is_null(
            $this->getContextualConcrete($abstract)
        );

        // If an instance of the type is currently being managed as a singleton we'll
        // just return an existing instance instead of instantiating new instances
        // so the developer can keep using the same objects instance every time.
        if (isset($this->instances[$abstract]) && ! $needsContextualBuild) {
            return $this->instances[$abstract];
        }

        $this->with[] = $parameters;

        $concrete = $this->getConcrete($abstract);

        // We're ready to instantiate an instance of the concrete type registered for
        // the binding. This will instantiate the types, as well as resolve any of
        // its "nested" dependencies recursively until all have gotten resolved.
        if ($this->isBuildable($concrete, $abstract)) {
            $object = $this->build($concrete);
        } else {
            $object = $this->make($concrete);
        }

        // If we defined any extenders for this type, we'll need to spin through them
        // and apply them to the object being built. This allows for the extension
        // of services, such as changing configuration or decorating the object.
        foreach ($this->getExtenders($abstract) as $extender) {
            $object = $extender($object, $this);
        }

        // If the requested type is registered as a singleton we'll want to cache off
        // the instances in "memory" so we can return it later without creating an
        // entirely new instance of an object on each subsequent request for it.
        if ($this->isShared($abstract) && ! $needsContextualBuild) {
            $this->instances[$abstract] = $object;
        }

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

        // Before returning, we will also set the resolved flag to "true" and pop off
        // the parameter overrides for this build. After those two things are done
        // we will be ready to return back the fully constructed class instance.
        $this->resolved[$abstract] = true;

        array_pop($this->with);

        return $object;
    }


你可能感兴趣的:(laravel 源码分析index make方法解析)