从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. CORS(跨域资源共享)跨域问题及解决

    当使用ajax跨域请求时,浏览器报错:XmlHttpRequest error: Origin null is not allowed by Access-Control-Allow-Origin.肯 ...

  2. YII编码规范

    类名称: 驼峰式 首字母大字 class PointController class PointRatioController 公共成员方法: 驼峰式 首字母小写 public function ge ...

  3. 【COCOS2DX-游戏开发之三四】cocos2dx 3.0 TableView特殊使用方法:滚动时不能选择等等

    cocos2dx 3.0版本号TableView拍生自ScrollView,经常使用来做滚动列表,有几种特殊使用方法,不知道大家用到过没 要求:1.滚动时不能选中TableCell,非滚动状态才干选中 ...

  4. JJG 623-2005 电阻应变仪计量检定规程

    JJG 623-2005 电阻应变仪计量检定规程 点击下载 JJG533-2007标准模拟应变量校准器检定规程 点击下载 JJG 533-1988标准(里面含有一些更具体的电路图供参考)

  5. 实例学习SSIS(一)--制作一个简单的ETL包

    原文:实例学习SSIS(一)--制作一个简单的ETL包 导读: 实例学习SSIS(一)--制作一个简单的ETL包 实例学习SSIS(二)--使用迭代 实例学习SSIS(三)--使用包配置 实例学习SS ...

  6. 所有MVP文章

    http://msdn.microsoft.com/zh-cn/dd346590.aspx

  7. [代码收藏]设为首页和加入收藏的JavaScript代码(兼容多浏览器)

    其实不少非IE内核浏览器都仍不支持通过代码将网页设为主页和加入收藏的功能,因此说是兼容,其实只是一个try,catch后的提醒而已. 加入收藏: /* * author : 2010-12-27 11 ...

  8. KMP算法简单回顾

    前言 虽从事企业应用的设计与开发,闲暇之时,还是偶尔涉猎数学和算法的东西,本篇根据个人角度来写一点关于KMP串匹配的东西,一方面向伟人致敬,另一方面也是练练手,头脑风暴.我在自娱自乐,路过的朋友别太认 ...

  9. switch与java,c#的异同

    <script type="text/javascript" language="javascript"> //JavaScript控制语句基本和以 ...

  10. VS2013全攻略(安装,技巧,快捷键,插件)!

    工欲善其事,必先利其器.VS2013全攻略(安装,技巧,快捷键,插件)! 之前一篇<c++的性能, c#的产能?!鱼和熊掌可以兼得,.NET NATIVE初窥>承蒙大家喜爱和编辑推荐,在此 ...