Laravel kernel例項化

TylerZou發表於2019-02-16

Laravel Kernel例項化

$kernel = $app->make(IlluminateContractsHttpKernel::class);

例項化 Kernel

  1. 在應用進行例項化時,已經初始化了很多的基礎操作,所以下面的構造方法將會直接使用服務容器的依賴注入來解決類之間的依賴關係。

    // IlluminateContractsHttpKernel 類構造器依賴 IlluminateContractsFoundationApplication 和 IlluminateRoutingRouter,將會通過服務容器來處理依賴關係
    public function __construct(Application $app, Router $router)
    {
        $this->app = $app;
    
        // 主要委託 $router 來處理
        $this->router = $router;
        // 以下均為中介軟體的設定
        $router->middlewarePriority = $this->middlewarePriority;
    
        foreach ($this->middlewareGroups as $key => $middleware) {
            $router->middlewareGroup($key, $middleware);
        }
    
        foreach ($this->routeMiddleware as $key => $middleware) {
            $router->aliasMiddleware($key, $middleware);
        }
    }
    
    IlluminateContractsFoundationApplication 的處理:
    make 時通過別名方式直接呼叫 $this->instances[`app`]
    
    IlluminateRoutingRouter 的處理:
    make 時通過別名方式直接呼叫 $this->bindings[`router`] 陣列裡面 concrete 對應的匿名函式
    Router 依賴 IlluminateContractsEventsDispatcher 和 IlluminateContainerContainer
    public function __construct(Dispatcher $events, Container $container = null)
    {
        $this->events = $events;
        $this->routes = new RouteCollection;
        $this->container = $container ?: new Container;
    }
    
    IlluminateContractsEventsDispatcher 的處理:
    make 時通過別名方式直接呼叫 $this->bindings[`events`] 陣列裡面 concrete 對應的匿名函式
    Dispatcher 依賴 IlluminateContractsContainerContainer
    public function __construct(ContainerContract $container = null)
    {
        $this->container = $container ?: new Container;
    }
    
    IlluminateContainerContainer 的處理:
    make 時直接呼叫 $this->instances[`IlluminateContainerContainer`] = Object(app)
    IlluminateContractsContainerContainer 的處理:
    make 時呼叫別名直接呼叫 $this->instances[`app`] = Object(app)
    上面兩個一樣,沒有區別
    

    注意:以上所列出的依賴關係,都直接委託給服務容器進行自動處理了,不需要怕怕

  2. 對 $this->bindings[`router`] 和 $this->bindings[`events`] 繫結事件的處理,make 時將會直接呼叫陣列鍵 concrete 對應的匿名函式。

    make 時使用到的程式碼片段

    ##############################################
    if ($concrete instanceof Closure) {            
        return $concrete($this, end($this->with)); 
    }
    ###############################################
    
    $this->bindings[`router`] = [
            `concrete` => function ($app) {
                                return new Router($app[`events`], $app);
                            },
            `shared` => `true`,
        ];
    $router = new Router($app[`events`], $app);
    
    IlluminateRoutingRouter
    public function __construct(Dispatcher $events, Container $container = null)
    {
        $this->events = $events;
        $this->routes = new RouteCollection;
        $this->container = $container ?: new Container;
    }
    

    返回一個 Router 物件,同時會重置 $this->instances[`router`] = $router 物件,供下次直接呼叫。

    $this->bindings[`events`] = [
        `concrete` => function ($app) {
                return (new Dispatcher($app))->setQueueResolver(function () use ($app) {
                    return $app->make(QueueFactoryContract::class);
                });
                }
        `shared` => `true`,
    ];
    
    $dispatcher = (new IlluminateEventsDispatcher($app))->setQueueResolver(function () use ($app) {
                    return $app->make(QueueFactoryContract::class);
                });
    
    IlluminateEventsDispatcher:
    public function __construct(ContainerContract $container = null)
    {
        $this->container = $container ?: new Container;
    }
    public function setQueueResolver(callable $resolver)
    {
        $this->queueResolver = $resolver;
    
        return $this;
    }
    

    返回一個 Dispatcher 物件,同時會重置 $this->instances[`events`] = $dispatcher 物件,供下次直接呼叫。

注意:
kernel物件是融合了應用和路由的物件,路由又注入了IlluminateEventsDispatcher物件,此為核心物件。

相關文章