从laravel入口文件index里面外面不难定位到Illuminate\Foundation\Http\Kernel的handle方法,同样也不难发现handle方法的核心是

$response = $this->sendRequestThroughRouter($request);

继续跟踪这个方法

/**
* Send the given request through the middleware / router.
*
* @param \Illuminate\Http\Request $request
* @return \Illuminate\Http\Response
*/
protected function sendRequestThroughRouter($request)
{
$this->app->instance('request', $request); Facade::clearResolvedInstance('request'); $this->bootstrap(); return (new Pipeline($this->app))
->send($request)
->through($this->app->shouldSkipMiddleware() ? [] : $this->middleware)
->then($this->dispatchToRouter());
}

今天我们要讨论的就是方法中的$this->bootstrap();

/**
* Bootstrap the application for HTTP requests.
*
* @return void
*/
public function bootstrap()
{
if (! $this->app->hasBeenBootstrapped()) {
$this->app->bootstrapWith($this->bootstrappers());
}
}

首先,我们先确定这个方法中的$this->app是类Illuminate\Foundation\Application以及$this->bootstrappers()如下所示数组

protected $bootstrappers = [
'Illuminate\Foundation\Bootstrap\DetectEnvironment',
'Illuminate\Foundation\Bootstrap\LoadConfiguration',
'Illuminate\Foundation\Bootstrap\ConfigureLogging',
'Illuminate\Foundation\Bootstrap\HandleExceptions',
'Illuminate\Foundation\Bootstrap\RegisterFacades',
'Illuminate\Foundation\Bootstrap\RegisterProviders',
'Illuminate\Foundation\Bootstrap\BootProviders',
];

那么接下来我们查看$this->app->bootstrapWith($this->bootstrappers())

/**
* Run the given array of bootstrap classes.
*
* @param array $bootstrappers
* @return void
*/
public function bootstrapWith(array $bootstrappers)
{
$this->hasBeenBootstrapped = true; foreach ($bootstrappers as $bootstrapper) {
$this['events']->fire('bootstrapping: '.$bootstrapper, [$this]); $this->make($bootstrapper)->bootstrap($this); $this['events']->fire('bootstrapped: '.$bootstrapper, [$this]);
} }

因为是粗粒度分析,我们同样只看这个方法的核心$this->make($bootstrapper)->bootstrap($this),$this->make($bootstrapper)这个我们简单的理解为new $bootstrapper即可,所以这句代码的意思就是将上面$bootstrappers数组里面的每个类实例化并调用他们的bootstrap方法,那么上面那些类都是干什么的呢,其实从类的名字也可以猜出大概的意思了。

Illuminate\Foundation\Bootstrap\DetectEnvironment::bootstrap,从名字看,像是检查环境,具体代码如下:

/**
* Bootstrap the given application.
*
* @param \Illuminate\Contracts\Foundation\Application $app
* @return void
*/
public function bootstrap(Application $app)
{
if (! $app->configurationIsCached()) {
$this->checkForSpecificEnvironmentFile($app); try {
          //$app->environmentPath()默认是我们的basePath,$app->environmentFile()默认是根目录里面的.env文件
(new Dotenv($app->environmentPath(), $app->environmentFile()))->load();
} catch (InvalidPathException $e) {
//
}
}
}

Illuminate\Foundation\Bootstrap\LoadConfiguration::bootstrap从名字看,像是加载配置,代码如下

/**
* Bootstrap the given application.
*
* @param \Illuminate\Contracts\Foundation\Application $app
* @return void
*/
public function bootstrap(Application $app)
{
$items = []; // First we will see if we have a cache configuration file. If we do, we'll load
// the configuration items from that file so that it is very quick. Otherwise
// we will need to spin through every configuration file and load them all.
if (file_exists($cached = $app->getCachedConfigPath())) {
$items = require $cached; $loadedFromCache = true;
} $app->instance('config', $config = new Repository($items)); // Next we will spin through all of the configuration files in the configuration
// directory and load each one into the repository. This will make all of the
// options available to the developer for use in various parts of this app.
if (! isset($loadedFromCache)) {
$this->loadConfigurationFiles($app, $config);
} $app->detectEnvironment(function () use ($config) {
return $config->get('app.env', 'production');
}); date_default_timezone_set($config['app.timezone']); mb_internal_encoding('UTF-8');
}

Illuminate\Foundation\Bootstrap\ConfigureLogging::bootstrap从名字看,像是配置日志,代码如下

/**
* Bootstrap the given application.
*
* @param \Illuminate\Contracts\Foundation\Application $app
* @return void
*/
public function bootstrap(Application $app)
{
     //大概就是默认使用Monolog作为日志记录
$log = $this->registerLogger($app); // If a custom Monolog configurator has been registered for the application
// we will call that, passing Monolog along. Otherwise, we will grab the
// the configurations for the log system and use it for configuration.
if ($app->hasMonologConfigurator()) {
call_user_func(
$app->getMonologConfigurator(), $log->getMonolog()
);
} else {
$this->configureHandlers($app, $log);
}
} /**
* Register the logger instance in the container.
*
* @param \Illuminate\Contracts\Foundation\Application $app
* @return \Illuminate\Log\Writer
*/
protected function registerLogger(Application $app)
{
$app->instance('log', $log = new Writer(
new Monolog($app->environment()), $app['events'])
); return $log;
}

Illuminate\Foundation\Bootstrap\HandleExceptions::bootstrap看名字,像是处理异常,代码如下

 /**
* Bootstrap the given application.
*
* @param \Illuminate\Contracts\Foundation\Application $app
* @return void
*/
public function bootstrap(Application $app)
{
$this->app = $app; error_reporting(-1); set_error_handler([$this, 'handleError']); set_exception_handler([$this, 'handleException']); register_shutdown_function([$this, 'handleShutdown']); if (! $app->environment('testing')) {
ini_set('display_errors', 'Off');
}
}

Illuminate\Foundation\Bootstrap\RegisterFacades::bootstrap看名字像是注册Facades,代码如下,config目录下app配置的aliases配置就是在这里加载的

/**
* Bootstrap the given application.
*
* @param \Illuminate\Contracts\Foundation\Application $app
* @return void
*/
public function bootstrap(Application $app)
{
Facade::clearResolvedInstances(); Facade::setFacadeApplication($app); AliasLoader::getInstance($app->make('config')->get('app.aliases', []))->register();
}

Illuminate\Foundation\Bootstrap\RegisterProviders::bootstrap看名字像是注册Providers,代码如下,config目录下app配置的providers配置就是在这里注册的

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

Illuminate\Foundation\Bootstrap\BootProviders::bootstrap看名字像是启动Providers,代码如下,其实就是执行上面注册的Providers数组中各个Provide的boot方法

/**
* Bootstrap the given application.
*
* @param \Illuminate\Contracts\Foundation\Application $app
* @return void
*/
public function bootstrap(Application $app)
{
$app->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.
$this->fireAppCallbacks($this->bootingCallbacks); array_walk($this->serviceProviders, function ($p) {
$this->bootProvider($p);
}); $this->booted = true; $this->fireAppCallbacks($this->bootedCallbacks);
}

我们经常安装一个扩展功能的时候需要去config里面的app.php的providers和aliases里面添加一些东西,通过以上的大概流程分析,我们就知道laravel是怎么处理这些东西的。

Laravel5.3 流程粗粒度分析之bootstrap的更多相关文章

  1. Ecshop的购物流程代码分析详细说明

    Ecshop的购物流程代码分析详细说明 (2012-07-30 10:41:12) 转载▼ 标签: 购物车 结算中心 商品价格 ecshop ecshop购物流程 杂谈 分类: ECSHOP研究院 同 ...

  2. 手机自动化测试:appium源码分析之bootstrap三

    手机自动化测试:appium源码分析之bootstrap三   研究bootstrap源码,我们可以通过代码的结构,可以看出来appium的扩展思路和实现方式,从中可以添加我们自己要的功能,针对app ...

  3. 手机自动化测试:appium源码分析之bootstrap二

    手机自动化测试:appium源码分析之bootstrap二   在bootstrap项目中的io.appium.android.bootstrap.handler包中的类都是对应的指令类, priva ...

  4. 手机自动化测试:appium源码分析之bootstrap一

    手机自动化测试:appium源码分析之bootstrap一   前言: poptest是国内唯一一家培养测试开发工程师的培训机构,以学员能胜任自动化测试,性能测试,测试工具开发等工作为目标.popte ...

  5. 手机自动化测试:appium源码分析之bootstrap十七

    手机自动化测试:appium源码分析之bootstrap十七   poptest是国内唯一一家培养测试开发工程师的培训机构,以学员能胜任自动化测试,性能测试,测试工具开发等工作为目标.如果对课程感兴趣 ...

  6. 手机自动化测试:appium源码分析之bootstrap十六

    手机自动化测试:appium源码分析之bootstrap十六   poptest是国内唯一一家培养测试开发工程师的培训机构,以学员能胜任自动化测试,性能测试,测试工具开发等工作为目标.如果对课程感兴趣 ...

  7. 手机自动化测试:appium源码分析之bootstrap十五

    手机自动化测试:appium源码分析之bootstrap十五   poptest是国内唯一一家培养测试开发工程师的培训机构,以学员能胜任自动化测试,性能测试,测试工具开发等工作为目标.如果对课程感兴趣 ...

  8. 手机自动化测试:appium源码分析之bootstrap十四

    手机自动化测试:appium源码分析之bootstrap十四   poptest(www.poptest.cn)是国内唯一一家培养测试开发工程师的培训机构,以学员能胜任自动化测试,性能测试,测试工具开 ...

  9. 手机自动化测试:appium源码分析之bootstrap十三

    手机自动化测试:appium源码分析之bootstrap十三   poptest(www.poptest.cn)是国内唯一一家培养测试开发工程师的培训机构,以学员能胜任自动化测试,性能测试,测试工具开 ...

随机推荐

  1. 面向对象JS基础讲解,工厂模式、构造函数模式、原型模式、混合模式、动态原型模式

    什么是面向对象?面向对象是一种思想!(废话). 面向对象可以把程序中的关键模块都视为对象,而模块拥有属性及方法.这样我们如果把一些属性及方法封装起来,日后使用将非常方便,也可以避免繁琐重复的工作.接下 ...

  2. PHP 10 : 流程控制

    原文:PHP 10 : 流程控制 感觉PHP和其他语言相似.说说PHP提供的流程控制关键字吧. 条件 ifelseelseifswitch 循环 whiledo{} while()breakconti ...

  3. 游戏开发常用JS

    游戏插件:cocos2d,createjs,webGl(3d),three.js(3d插件) web插件:Bootstrap插件.less尽量写在服务端. chart.js:精巧的js图标绘制工具库

  4. 如何有效的遍历django的QuerySet

    最近做了一个小的需求,在django模型中通过前台页面的表单的提交(post),后台对post的参数进行解析,通过models模型查询MySQL,将数据结构进行加工,返回到前台页面进行展示.由于对dj ...

  5. 无线连接手机进行Android测试

    当每天走到哪都要拿一根数据线进行项目测试的时候,总是有一些焦急和烦躁的,如果能够无线连接测试就在好不过了. 这样不再是什么难事了,只需要几步走: 在进行无线连接测试的过程中,你的手机必须root了,这 ...

  6. Varnish缓存服务详解及应用实现

    1.varnish的基本介绍    Varnish 的作者Poul-Henning Kamp是FreeBSD的内核开发者之一,他认为现在的计算机比起1975年已经复杂许多.在1975年时,储存媒介只有 ...

  7. 对Extjs中store的多种操作

    Store.getCount()返回的是store中的所有数据记录,然后使用for循环遍历整个store,从而得到每条记录. 除了使用getCount()的方法外,还可以使用each()函数,如下面的 ...

  8. leetcode Binary Tree Postorder Traversal 二叉树后续遍历

    先给出递归版本的实现方法,有时间再弄个循环版的.代码如下: /** * Definition for binary tree * struct TreeNode { * int val; * Tree ...

  9. Binder机制,从Java到C (9. IPC通信过程)

    1.一次IPC通信過程的幾個步驟 一次通信过程简单的说有下面5个步骤,第一眼看上去,肯定不知道什么玩意,多看几遍,慢慢看,其实是能理解的. 1. Client将数据封装成Parcel. (前面已经讲过 ...

  10. POJ 1002 UVA 755 487--3279 电话排序 简单但不容易的水题

    题意:给你许多串字符串,从中提取电话号码,输出出现复数次的电话号码及次数. 以下是我艰难的AC历程:(这题估计是我刷的题目题解次数排前的了...) 题目不是很难理解,刚开始想到用map,但stl的ma ...