请求到响应的核个执行过程,主要可以归纳为四个阶段,即程序启动准备阶段、请求实例化阶段、请求处理阶段、响应发送和程序终止阶段。

public\index.php中有这么一段代码

$app = require_once __DIR__.'/../bootstrap/app.php';
//app.php
<?php
//用来实现服务容器的实例化过程
$app = new Illuminate\Foundation\Application(
realpath(__DIR__.'/../')
); //下面代码向服务容器中绑定核心类服务,并返回核心类服务 $app->singleton(
Illuminate\Contracts\Http\Kernel::class,
App\Http\Kernel::class
); $app->singleton(
Illuminate\Contracts\Console\Kernel::class,
App\Console\Kernel::class
); $app->singleton(
Illuminate\Contracts\Debug\ExceptionHandler::class,
App\Exceptions\Handler::class
); return $app;

 Illuminate\Foundation\Application

class Application extends Container implements ApplicationContract, HttpKernelInterface
public function __construct($basePath = null)
{
if ($basePath) {
//注册应用的基础路径
$this->setBasePath($basePath);
} //用来绑定基础服务,主要是绑定容器实例本身,是的其它对象可以很容易得到服务容器实例
$this->registerBaseBindings();
//注册基础服务提供者
$this->registerBaseServiceProviders();
//注册核心类别名和应用的基础路径
$this->registerCoreContainerAliases();
}

setBasePath

    public function setBasePath($basePath)
{
$this->basePath = rtrim($basePath, '\/');
//在容器中绑定应用程序的基础路径
$this->bindPathsInContainer(); return $this;
}
registerBaseBindings
    protected function registerBaseBindings()
{
static::setInstance($this); $this->instance('app', $this); $this->instance(Container::class, $this); $this->instance(PackageManifest::class, new PackageManifest(
new Filesystem, $this->basePath(), $this->getCachedPackagesPath()
));
} public function instance($abstract, $instance)
{
$this->removeAbstractAlias($abstract); $isBound = $this->bound($abstract); unset($this->aliases[$abstract]); // We'll check to determine if this type has been bound before, and if it has
// we will fire the rebound callbacks registered with the container and it
// can be updated with consuming classes that have gotten resolved here.
$this->instances[$abstract] = $instance; if ($isBound) {
$this->rebound($abstract);
} return $instance;
}
registerBaseServiceProviders
    protected function registerBaseServiceProviders()
{
$this->register(new EventServiceProvider($this)); $this->register(new LogServiceProvider($this)); $this->register(new RoutingServiceProvider($this));
} public function register($provider, $options = [], $force = false)
{
//如果服务者已经存在 则获取这个实例对象
if (($registered = $this->getProvider($provider)) && ! $force) {
return $registered;
} //通过类名实例化一个服务提供者
if (is_string($provider)) {
$provider = $this->resolveProvider($provider);
}
//向服务容器中注册服务
if (method_exists($provider, 'register')) {
//每个服务提供者必须实现这个函数,用来填充服务器并提供服务
$provider->register();
}
//标识该服务提供者已经注册过了
$this->markAsRegistered($provider);
if ($this->booted) {
//启动规定的服务器供者 并且会调用服务提供者的boot函数
//boot这个函数服务提供者可以不用实现
$this->bootProvider($provider);
}
return $provider;
}
registerCoreContainerAliases  :定义了整个框架的核心服务别名
    public function registerCoreContainerAliases()
{
foreach ([
'app' => [\Illuminate\Foundation\Application::class, \Illuminate\Contracts\Container\Container::class, \Illuminate\Contracts\Foundation\Application::class, \Psr\Container\ContainerInterface::class],
'auth' => [\Illuminate\Auth\AuthManager::class, \Illuminate\Contracts\Auth\Factory::class],
'auth.driver' => [\Illuminate\Contracts\Auth\Guard::class],
'blade.compiler' => [\Illuminate\View\Compilers\BladeCompiler::class],
'cache' => [\Illuminate\Cache\CacheManager::class, \Illuminate\Contracts\Cache\Factory::class],
'cache.store' => [\Illuminate\Cache\Repository::class, \Illuminate\Contracts\Cache\Repository::class],
'config' => [\Illuminate\Config\Repository::class, \Illuminate\Contracts\Config\Repository::class],
'cookie' => [\Illuminate\Cookie\CookieJar::class, \Illuminate\Contracts\Cookie\Factory::class, \Illuminate\Contracts\Cookie\QueueingFactory::class],
'encrypter' => [\Illuminate\Encryption\Encrypter::class, \Illuminate\Contracts\Encryption\Encrypter::class],
'db' => [\Illuminate\Database\DatabaseManager::class],
'db.connection' => [\Illuminate\Database\Connection::class, \Illuminate\Database\ConnectionInterface::class],
'events' => [\Illuminate\Events\Dispatcher::class, \Illuminate\Contracts\Events\Dispatcher::class],
'files' => [\Illuminate\Filesystem\Filesystem::class],
'filesystem' => [\Illuminate\Filesystem\FilesystemManager::class, \Illuminate\Contracts\Filesystem\Factory::class],
'filesystem.disk' => [\Illuminate\Contracts\Filesystem\Filesystem::class],
'filesystem.cloud' => [\Illuminate\Contracts\Filesystem\Cloud::class],
'hash' => [\Illuminate\Contracts\Hashing\Hasher::class],
'translator' => [\Illuminate\Translation\Translator::class, \Illuminate\Contracts\Translation\Translator::class],
'log' => [\Illuminate\Log\Writer::class, \Illuminate\Contracts\Logging\Log::class, \Psr\Log\LoggerInterface::class],
'mailer' => [\Illuminate\Mail\Mailer::class, \Illuminate\Contracts\Mail\Mailer::class, \Illuminate\Contracts\Mail\MailQueue::class],
'auth.password' => [\Illuminate\Auth\Passwords\PasswordBrokerManager::class, \Illuminate\Contracts\Auth\PasswordBrokerFactory::class],
'auth.password.broker' => [\Illuminate\Auth\Passwords\PasswordBroker::class, \Illuminate\Contracts\Auth\PasswordBroker::class],
'queue' => [\Illuminate\Queue\QueueManager::class, \Illuminate\Contracts\Queue\Factory::class, \Illuminate\Contracts\Queue\Monitor::class],
'queue.connection' => [\Illuminate\Contracts\Queue\Queue::class],
'queue.failer' => [\Illuminate\Queue\Failed\FailedJobProviderInterface::class],
'redirect' => [\Illuminate\Routing\Redirector::class],
'redis' => [\Illuminate\Redis\RedisManager::class, \Illuminate\Contracts\Redis\Factory::class],
'request' => [\Illuminate\Http\Request::class, \Symfony\Component\HttpFoundation\Request::class],
'router' => [\Illuminate\Routing\Router::class, \Illuminate\Contracts\Routing\Registrar::class, \Illuminate\Contracts\Routing\BindingRegistrar::class],
'session' => [\Illuminate\Session\SessionManager::class],
'session.store' => [\Illuminate\Session\Store::class, \Illuminate\Contracts\Session\Session::class],
'url' => [\Illuminate\Routing\UrlGenerator::class, \Illuminate\Contracts\Routing\UrlGenerator::class],
'validator' => [\Illuminate\Validation\Factory::class, \Illuminate\Contracts\Validation\Factory::class],
'view' => [\Illuminate\View\Factory::class, \Illuminate\Contracts\View\Factory::class],
] as $key => $aliases) {
foreach ($aliases as $alias) {
$this->alias($key, $alias);
}
}
}

至此应用程序的准备工作已经完成  

接下来我们再来看看index.php

/**
* 主要实现了服务容器的实例化和基本注册
*包括服务容器本身的注册,基础服务提供者注册,核心类别名注册和基本路径注册
*
*/
$kernel = $app->make(Illuminate\Contracts\Http\Kernel::class);

//处理请求
$response = $kernel->handle(
//请求实例的创建
$request = Illuminate\Http\Request::capture()
);
namespace Illuminate\Foundation\Http\Kernel
    /**
* Handle an incoming HTTP request.
*处理一个http请求
* @param \Illuminate\Http\Request $request
* @return \Illuminate\Http\Response
*/
public function handle($request)
{
try {
//在请求过程中会添加CSRF保护,服务端会发送一个csrf令牌给客户端(cookie)
$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);
} $this->app['events']->dispatch(
new Events\RequestHandled($request, $response)
); return $response;
}
    protected function sendRequestThroughRouter($request)
{
$this->app->instance('request', $request); Facade::clearResolvedInstance('request'); //针对请求为应用程序'拔靴带' 执行bootstrap类的数组
//在请求处理阶段共有7个环节,每一个环节由一个类来实现的
//而且每个类都会有一个bootstrap()函数用于实现准备工作
$this->bootstrap(); return (new Pipeline($this->app))
->send($request)
->through($this->app->shouldSkipMiddleware() ? [] : $this->middleware)
->then($this->dispatchToRouter());
}

 

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

\vendor\laravel\framework\src\Illuminate\Foundation\Application.php 

    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]);
}
}

  

    protected $bootstrappers = [
\Illuminate\Foundation\Bootstrap\LoadEnvironmentVariables::class,
\Illuminate\Foundation\Bootstrap\LoadConfiguration::class,//环境检测与配置加载
\Illuminate\Foundation\Bootstrap\HandleExceptions::class,
\Illuminate\Foundation\Bootstrap\RegisterFacades::class,//外观注册
\Illuminate\Foundation\Bootstrap\RegisterProviders::class,//服务提供者注册
\Illuminate\Foundation\Bootstrap\BootProviders::class,//启动服务
];

  

接下来讲讲 服务提供者注册和启动服务
\Illuminate\Foundation\Bootstrap\RegisterProviders::class,//服务提供者注册
//服务提供者注册
public function bootstrap(Application $app)
{
$app->registerConfiguredProviders();
}

在Application中注册所有配置的服务提供者
    public function registerConfiguredProviders()
{
$providers = Collection::make($this->config['app.providers'])
->partition(function ($provider) {
return Str::startsWith($provider, 'Illuminate\\');
}); $providers->splice(1, 0, [$this->make(PackageManifest::class)->providers()]); (new ProviderRepository($this, new Filesystem, $this->getCachedServicesPath()))
->load($providers->collapse()->toArray());
}
    /**
* //注册应用的服务提供者
*
* @param array $providers
* @return void
*/
public function load(array $providers)
{
//加载Laravel\bootstrap\cache\services.json文件
$manifest = $this->loadManifest(); //加载服务清单,这里包含程序所有的服务提供者并进行分类
if ($this->shouldRecompile($manifest, $providers)) {
$manifest = $this->compileManifest($providers);
} //服务提供者加载时间,当这个事件发生时才自动加载这个服务提供者
foreach ($manifest['when'] as $provider => $events) {
$this->registerLoadEvents($provider, $events);
} //提前注册那些必须加载的服务提供者,以此为应用提供服务
foreach ($manifest['eager'] as $provider) {
$this->app->register($provider);
}
//在列表中江路延迟加载的服务提供者,需要时再加载
$this->app->addDeferredServices($manifest['deferred']);
}

  服务提供者都继承于服务提供者基类(Illuminate\Support\ServiceProvider),该类是一个抽象类,其中定义了一个抽象函数register(),所以每个服务提供者都需要实现该函数,而该函数中实现了服务注册的内容

  

  

启动服务

在这最后一步中:服务提供者必须要实现register()函数,还有一个boot()函数根据需要决定是否实现,主要用于启动服务;对于boot()函数的服务提供者,会通过下面类统一管理调用
\Illuminate\Foundation\Bootstrap\BootProviders::class,//启动服务
    public function bootstrap(Application $app)
{
$app->boot();
}

 在服务容器vendor\laravel\framework\src\Illuminate\Foundation\Application.php代码中

public function boot()
{
if ($this->booted) {
return;
} $this->fireAppCallbacks($this->bootingCallbacks); array_walk($this->serviceProviders, function ($p) {
$this->bootProvider($p);
}); $this->booted = true; $this->fireAppCallbacks($this->bootedCallbacks);
} protected function bootProvider(ServiceProvider $provider)
{
if (method_exists($provider, 'boot')) {
return $this->call([$provider, 'boot']);
}
}

  

从上面可以看到,在 Larave !应用程序的服务容器中保存了服务提供者的实例数组,即 $serviceProviders 属性:
这单包含了服务容器实例化过程中注册的两个基础服务提供者及在服务提供者注册过程中注册的 eagc :类服务提供者,
然后通过代码“ $this->caIl([$provider,'boot']); $SserviceProviders 属性中记录的每一个服务提供者实例的 boot()函数,
该函数主要是对相应的服务进行初始化,

下一章节:中间件

laravel请求到响应的生命周期的更多相关文章

  1. Laravel学习:请求到响应的生命周期

    Laravel请求到响应的整个执行过程,主要可以归纳为四个阶段,即程序启动准备阶段.请求实例化阶段.请求处理阶段.响应发送和程序终止阶段. 程序启动准备阶段 服务容器实例化 服务容器的实例化和基本注册 ...

  2. python---django请求-响应的生命周期(FBV和CBV含义)

    Django请求的生命周期是指:当用户在访问该url路径是,在服务器Django后台都发生了什么. 客户端发送Http请求给服务端,Http请求是一堆字符串,其内容是: 访问:http://crm.o ...

  3. Laravel 入口文件解读及生命周期

    这里只贴index.php的代码, 深入了解的请访问    https://laravel-china.org/articles/10421/depth-mining-of-laravel-life- ...

  4. ASP.NET MVC5 的请求管道和运行生命周期

    https://www.jianshu.com/p/848fda7f79e0 请求处理管道 请求管道是一些用于处理HTTP请求的模块组合,在ASP.NET中,请求管道有两个核心组件:IHttpModu ...

  5. asp.net请求管道和页面生命周期

  6. Envoy 代理中的请求的生命周期

    Envoy 代理中的请求的生命周期 翻译自Envoy官方文档. 目录 Envoy 代理中的请求的生命周期 术语 网络拓扑 配置 高层架构 请求流 总览 1.Listener TCP连接的接收 2.监听 ...

  7. Net6 DI源码分析Part5 在Kestrel内Di Scope生命周期是如何根据请求走的?

    Net6 DI源码分析Part5 在Kestrel内Di Scope生命周期是如何根据请求走的? 在asp.net core中的DI生命周期有一个Scoped是根据请求走的,也就是说在处理一次请求时, ...

  8. asp.net MVC 应用程序的生命周期

    下面这篇文章总结了 asp.net MVC 框架程序的生命周期.觉得写得不错,故转载一下. 转载自:http://www.cnblogs.com/yplong/p/5582576.html       ...

  9. ASP.NET 页生命周期

    ASP.NET 页运行时,此页将经历一个生命周期,在生命周期中将执行一系列处理步骤.这些步骤包括初始化.实例化控件.还原和维护状态.运行事件处理程序代码以及进行 呈现.了解页生命周期非常重要,因为这样 ...

随机推荐

  1. BZOJ 1064: [Noi2008]假面舞会(dfs + 图论好题!)

    http://www.lydsy.com/JudgeOnline/problem.php?id=1064 题意: 思路: 考虑以下几种情况: ①无环并且是树: 无环的话就是树结构了,树结构的话想一下就 ...

  2. React内三种函数的写法

     以下提供三种React内函数的写法,都可以正常运行,有疑问可以留言 写法一:让函数内部的this指向这个类的实例,它是用bind实现的,bind的第一个参数表示context,就是this. //写 ...

  3. webpack插件配置(一) webpack-dev-server 路径配置

    本文的路径配置主要涉及到webpack.config.js文件中devServer与output两个选项的配置 webpack-dev-server定义 webpack-dev-server主要是启动 ...

  4. wow.js

    一.首先说明一下怎么使用这个插件: 1.wow.js依赖于animate.css,首先在头部引用animate.css或者animate.min.css. <link rel="sty ...

  5. 【BZOJ】4011: [HNOI2015]落忆枫音

    题目链接:http://blog.csdn.net/popoqqq/article/details/45194103 写代码的时候也没有很清晰....具体看这里吧 #include<iostre ...

  6. springboot学习之授权Spring Security

    SpringSecurity核心功能:认证.授权.攻击防护(防止伪造身份) 涉及的依赖如下: <dependency> <groupId>org.springframework ...

  7. 1.0 poi单元格合合并及写入

    最近项目中用到poi生成Excel时,用到了单元格合并,于是参考了http://www.anyrt.com/blog/list/poiexcel.html写的文章,但是其中有些地方不是很清楚,于是自己 ...

  8. Oracle(限定查询2)

    3.2 对数据进行限定查询 在标准SQL之中定义了许多的运算符. 3.2.1.关系运算符 范例: 范例: 范例: 在使用关系运算符判断字符数据的时候注意大小写的编写问题.因为Oracle是区分大小写的 ...

  9. VC.判断双字节字符集前导字节集(IsDBCSLeadByte)

    ZC:这是 WIndows API 函数 1.“BOOL IsDBCSLeadByte( char );” 判断 某字节是否在 双字节字符集的前导字节集中 ZC:可以判断  如 汉字.日文.韩文等 Z ...

  10. link和@import区别

    推荐使用:link 区别 1.从属关系区别@import是 CSS 提供的语法规则,只有导入样式表的作用:link是HTML提供的标签,不仅可以加载 CSS 文件,还可以定义 RSS.rel 连接属性 ...