参考资料:
php:laravel底层核心代码分析之make方法的实现
Laravel加载过程---make方法

实例化Illuminate\Contracts\Http\Kernel

make方法

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

$kernel = $app->make(Illuminate\Contracts\Http\Kernel::class);
$app->make() => 父类Application中的make() => resolve()方法

resolve方法

vendor/laravel/framework/src/Illuminate/Container/Container.php
/**
 * 第一次调用
 * $abstract Illuminate\Contracts\Http\Kernel::class
 * $concrete 匿名函数
 * 
 * 第二次调用
 * $abstract 'App\Http\Kernel'
 * $concrete 'App\Http\Kernel' (getConcrete方法返回)
 * 执行build()方法获取App\Http\Kernel的实例化对象,返回给getClosure()
 */
protected function resolve($abstract, $parameters = [], $raiseEvents = true)
{   
    ...
    //根据$abstract从bindings数组中获取$concrete匿名函数
    $concrete = $this->getConcrete($abstract);
    //判断$concrete和$abstract是否相同,或者$concrete是一个匿名函数
    if ($this->isBuildable($concrete, $abstract)) {
        //实例化$concrete的类
        $object = $this->build($concrete);
    } else {
        //递归执行make
        $object = $this->make($concrete);
    }
    ...
 }   

getClosure()方法递归调用

/**
 * 第一次调用
 * $abstract 'Illuminate\Contracts\Http\Kernel'
 * $concrete 'App\Http\Kernel'
 * 
 * 第二次调用
 * 获取App\Http\Kernel的实例,向上返回给build()方法
 */
protected function getClosure($abstract, $concrete)
{
    return function ($container, $parameters = []) use ($abstract, $concrete) {
        if ($abstract == $concrete) {
            return $container->build($concrete);
        }
        return $container->resolve($concrete, $parameters, $raiseEvents = false);
    };
}

build方法

vendor/laravel/framework/src/Illuminate/Container/Container.php
/**
 * 第一次调用
 * $concrete 匿名函数
 * 
 * 第二次调用
 * $concrete 'App\Http\Kernel' 
 * 执行反射,获取App\Http\Kernel类的实例化对象
 * 返回给resolve()方法
 */
public function build($concrete)
{
    if ($concrete instanceof Closure) {
        //bind()方法中$concrete = $this->getClosure($abstract, $concrete);
        return $concrete($this, $this->getLastParameterOverride());
    }
    $reflector = new ReflectionClass($concrete);
    if (! $reflector->isInstantiable()) {
        return $this->notInstantiable($concrete);
    }
    $this->buildStack[] = $concrete;
    $constructor = $reflector->getConstructor();
    if (is_null($constructor)) {
        array_pop($this->buildStack);
        return new $concrete;
    }
    $dependencies = $constructor->getParameters();
    $instances = $this->resolveDependencies(
        $dependencies
    );
    array_pop($this->buildStack);
    return $reflector->newInstanceArgs($instances);
}

流程图示例


IT小马
1.2k 声望166 粉丝

Php - Go - Vue - 云原生