Laravel源码入门-启动引导过程(五)$kernel->handle($request)
2017-05-14 17:20
656 查看
接上文,《Laravel源码入门-启动引导过程(四)app/Http/Kernel.php》,说,Kernel 做了两件事,第一个是定义 $bootstraps[],做好了 boot 系统的准备,第二个是定义 各种 middleware,这些都对 $request 进行加工、处理、甄选、判断,最终为可以形成正确的、有效的 $response 做准备,都完成后,进行了 index.php 中的 $kernel->handle($request),返回 $response。
仔细分析发现,public/index.php 中 $kernel 在make() 时,真的只是做了准备,真正的载入环境变量(.env)、根据配置载入 Service Providers 等,实际在 $kernel->handle($request) 语句中进行。先贴出加入测试 echo 记录下的载入过程结果。
下面具体看一下 Illuminate\Foundation\Http\Kernel.php 的 handle() 及相关代码片段。
=== 总结 ===
如先期描述的 handle() 通过 sendRequestThroughtRouter($request) 处理请求,返回 $response,途中进行了 启动引导,$this->bootstrap(),进一步调用 Application 的 bootstrapWith(),将自己定义的 bootstrapper[] 传入,这个 bootstrappers[] 如前定义,包括了载入服务器环境变量、配置信息、服务提供者、异常处理等。一切结束后,没有抛出异常的话,返回 public/index.php,正如开始的 echo 记录一样。
附:Application 中 bootstrapWith() 代码
仔细分析发现,public/index.php 中 $kernel 在make() 时,真的只是做了准备,真正的载入环境变量(.env)、根据配置载入 Service Providers 等,实际在 $kernel->handle($request) 语句中进行。先贴出加入测试 echo 记录下的载入过程结果。
// 开始 public/index.php $app = require_once __DIR__.'/../bootstrap/app.php' $kernel = $app->make(Illuminate\Contracts\Http\Kernel::class); start-->$response = $kernel->handle() // 进入 Illuminate/Foundation/Http/Kernel.php Foundation/Http/Kernel::handle() Foundation/Http/Kernel::sendRequestThroughRouter() Foundation/Http/Kernel::bootstrap() // 进入 Illumniate/Foundation/Application.php Foundation/Application::bootstrapWith($bootstrapWith) Illuminate\Foundation\Bootstrap\LoadEnvironmentVariables Illuminate\Foundation\Bootstrap\LoadConfiguration reading config/app.php Illuminate\Foundation\Bootstrap\HandleExceptions Illuminate\Foundation\Bootstrap\RegisterFacades Illuminate\Foundation\Bootstrap\RegisterProviders Illuminate\Foundation\Bootstrap\BootProviders // 回到 public/index.php end<---$response = $kernel->handle()
下面具体看一下 Illuminate\Foundation\Http\Kernel.php 的 handle() 及相关代码片段。
// 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, ]; // 此处省略无关代码 /** * Handle an incoming HTTP request. 处理请求的 handle() * * @param \Illuminate\Http\Request $request * @return \Illuminate\Http\Response */ public function handle($request) { echo 'Foundation/Http/Kernel::handle() <br />'; try { $request->enableHttpMethodParameterOverride(); // 将请求发送至中间件、路由处理。 $response = $this->sendRequestThroughRouter($request); } catch (Exception $e) { $this->reportException($e); $response = $this->renderException($request, $e); } catch (Throwable $e) { $this->reportException($e = new FatalThrowableError($e)); $response = $this->renderException($request, $e); } event(new Events\RequestHandled($request, $response)); return $response; } /** * Send the given request through the middleware / router. * 将请求发送至中间件、路由处理。 * * @param \Illuminate\Http\Request $request * @return \Illuminate\Http\Response */ protected function sendRequestThroughRouter($request) { echo 'Foundation/Http/Kernel::sendRequestThroughRouter() <br />'; $this->app->instance('request', $request); Facade::clearResolvedInstance('request'); // Kernel 要启动引导 $this->bootstrap(); return (new Pipeline($this->app)) ->send($request) ->through($this->app->shouldSkipMiddleware() ? [] : $this->middleware) ->then($this->dispatchToRouter()); } /** * Bootstrap the application for HTTP requests. * 启动引导(requests 驱动) * * @return void */ public function bootstrap() { echo 'Foundation/Http/Kernel::bootstrap() <br />'; if (! $this->app->hasBeenBootstrapped()) { // 使用 Application 的 bootstrapWith()方法启动引导 // 参数是 Kernel 中的 bootstrapers[]。 $this->app->bootstrapWith($this->bootstrappers()); } }
=== 总结 ===
如先期描述的 handle() 通过 sendRequestThroughtRouter($request) 处理请求,返回 $response,途中进行了 启动引导,$this->bootstrap(),进一步调用 Application 的 bootstrapWith(),将自己定义的 bootstrapper[] 传入,这个 bootstrappers[] 如前定义,包括了载入服务器环境变量、配置信息、服务提供者、异常处理等。一切结束后,没有抛出异常的话,返回 public/index.php,正如开始的 echo 记录一样。
附:Application 中 bootstrapWith() 代码
// Illuminate\Foundation\Application.php 代码片段 /** * Run the given array of bootstrap classes. * * @param array $bootstrappers * @return void */ public function bootstrapWith(array $bootstrappers) { echo 'Foundation/Application::bootstrapWith($bootstrapWith) <br />'; $this->hasBeenBootstrapped = true; foreach ($bootstrappers as $bootstrapper) { echo $bootstrapper . '<br />'; $this['events']->fire('bootstrapping: '.$bootstrapper, [$this]); // 解析每个 $bootstrapper,由调用他们自身的 bootstrap(),引导。 $this->make($bootstrapper)->bootstrap($this); $this['events']->fire('bootstrapped: '.$bootstrapper, [$this]); } }
相关文章推荐
- Laravel源码入门-启动引导过程(二)bootstrap/autoload.php
- Laravel源码入门-启动引导过程(四)app/Http/Kernel.php
- Laravel源码入门-启动引导过程(八)HandleExceptions
- Laravel源码入门-启动引导过程(七)LoadConfiguration
- <linux是怎么跑的?>傻瓜视角看linux引导启动过程
- Laravel源码入门-启动引导过程(三)bootstrap/app.php
- Laravel源码入门-启动引导过程(一)public/index.php
- Laravel源码入门-启动引导过程(十)RegisterProviders
- Laravel源码入门-启动引导过程(十二)Pipeline
- Laravel源码入门-启动引导过程(十一)BootProviders
- Laravel源码入门-启动引导过程(六)LoadEnvironmentVariables
- <linux是怎么跑的?>傻瓜视角看linux引导启动过程
- Laravel源码入门-启动引导过程(九)RegisterFacades
- linux grub 引导启动过程详解
- kernel 启动过程之四,start_kernel中的rest_init函数到init进程
- Linux启动过程详解1>
- Linux系统程序启动引导过程详细剖析
- Linux系统启动过程及grub引导故障排错(二)
- Linux系统启动过程及grub引导故障排错(一)
- kernel 启动过程之五, initcall 的来由, console 的初始化