您的位置:首页 > 编程语言 > PHP开发

Laravel源码入门-启动引导过程(十一)BootProviders

2017-05-24 22:24 381 查看
上文介绍了 RegisterProviders,在 《Laravel源码入门-启动引导过程(五)$kernel->handle($request)》中第六个要载入的是 BootProviders,也就是 Foundation\Http\Kernel::bootstrapers[] 的第六个

\Illuminate\Foundation\Bootstrap\BootProviders::class, 如下:



// Illuminate\Foundation\Http\Kernel.php 片段

/**
* The bootstrap classes for the application.
* 引导类,起引导作用的类
*
* @var array
*/
protected $bootstrappers = [
// 载入服务器环境变量(.env 文件)
\Illuminate\Foundation\Bootstrap\LoadEnvironmentVariables::class,
// 载入配置信息(config 目录)
\Illuminate\Foundation\Bootstrap\LoadConfiguration::class,
// 配置如何处理异常
\Illuminate\Foundation\Bootstrap\HandleExceptions::class,
// 注册 Facades
\Illuminate\Foundation\Bootstrap\RegisterFacades::class,
// 注册 Providers
\Illuminate\Foundation\Bootstrap\RegisterProviders::class,
// 启动 Providers
\Illuminate\Foundation\Bootstrap\BootProviders::class,
];

我们再直接贴出 BootProviders 类的代码,进行分析,非常直观,如下

<?php

namespace Illuminate\Foundation\Bootstrap;

use Illuminate\Contracts\Foundation\Application;

class BootProviders
{
/**
* Bootstrap the given application.
*
* @param  \Illuminate\Contracts\Foundation\Application  $app
* @return void
*/
public function bootstrap(Application $app)
{
$app->boot();
}
}

本来至此,BootProviders 就结束了,但再深入一步,我们看看 Application::boot() 的源代码:

/**
* Boot the application's service providers.
*
* @return void
*/
public function boot()
{
if ($this->booted) {
return;
}

// Once the application has booted we will also fire some "booted" callbacks
// for any listeners that need to do work after this initial booting gets
// finished. This is useful when ordering the boot-up processes we run.

// 这里发起 booting 的回调处理
$this->fireAppCallbacks($this->bootingCallbacks);

// 调用多个 Providers 的 boot 方法。
// 查看 $this->bootProvider(ServiceProvider $provider)可知。
array_walk($this->serviceProviders, function ($p) {
$this->bootProvider($p);
});

// 修改状态
$this->booted = true;

// 这里发起 booted 的回调处理
$this->fireAppCallbacks($this->bootedCallbacks);
}

再列出 $this->fireAppCallbacks() 的源代码,简单易懂:

/**
* Call the booting callbacks for the application.
*
* @param  array  $callbacks
* @return void
*/
protected function fireAppCallbacks(array $callbacks)
{
foreach ($callbacks as $callback) {
call_user_func($callback, $this);
}
}

再列出 $this->bootProider() 的源代码,

/**
* Boot the given service provider.
*
* @param  \Illuminate\Support\ServiceProvider  $provider
* @return mixed
*/
protected function bootProvider(ServiceProvider $provider)
{
if (method_exists($provider, 'boot')) {
return $this->call([$provider, 'boot']);
}
}

这里调用的是每个 Provider 的 boot() 方法。

=== 下面距离,是 RouteServiceProvider 的 boot()方法,以被考察:===

<?php

namespace Illuminate\Foundation\Support\Providers;

use Illuminate\Routing\Router;
use Illuminate\Support\ServiceProvider;
use Illuminate\Contracts\Routing\UrlGenerator;

class RouteServiceProvider extends ServiceProvider
{
/**
* The controller namespace for the application.
*
* @var string|null
*/
protected $namespace;

/**
* Bootstrap any application services.
*
* @return void
*/
public function boot()
{
$this->setRootControllerNamespace();

if ($this->app->routesAreCached()) {
$this->loadCachedRoutes();
} else {
$this->loadRoutes();

$this->app->booted(function () {
$this->app['router']->getRoutes()->refreshNameLookups();
$this->app['router']->getRoutes()->refreshActionLookups();
});
}
}

路由的 boot() 机制挺简单,设置控制器的根目录命名空间,直接载入路由或从缓存载入,laodRoutes()方法就是调用对应的 map() 方法,最后一步是,回调处理,booted 后,执行 Application::booted($callback),这里更新路由的名称查询列表(name look-up list)和 动作的查询列表(action look-up list)。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息