Laravel源码入门-启动引导过程(十一)BootProviders
博客专区 > zhmsong 的博客 > 博客详情
Laravel源码入门-启动引导过程(十一)BootProviders
zhmsong 发表于5个月前
Laravel源码入门-启动引导过程(十一)BootProviders
  • 发表于 5个月前
  • 阅读 9
  • 收藏 0
  • 点赞 0
  • 评论 0

腾讯云 十分钟定制你的第一个小程序>>>   

上文介绍了 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)。

 

共有 人打赏支持
粉丝 38
博文 126
码字总数 65130
×
zhmsong
如果觉得我的文章对您有用,请随意打赏。您的支持将鼓励我继续创作!
* 金额(元)
¥1 ¥5 ¥10 ¥20 其他金额
打赏人
留言
* 支付类型
微信扫码支付
打赏金额:
已支付成功
打赏金额: