laravel的启动需要通过路由、中间件、控制器、模型、视图最后出现在浏览器。而路由、中间件、模型,这些功能都有自己的类,比如Route::any()、DB::table()、$this->middleware()等等,这些功能都是由一个叫IOC(服务容器)的对象来调配的。
它就像框架里的一个管家,我们需要某些功能的时候不需要去自己new、去考虑运行这A对象还需要把哪些对象传入A对象里才能运行了。laravel的index入口文件只管制造一个ioc实例,然后把request对象传入其中。
ioc容器中有一个叫provider的概念,大多数功能都有一个provider,它的作用就是把一个功能需要用到的类,这些类的路径及所需要的一些东西记录起来,在ioc实例化的时候调用其中一些基础服务。ioc在实例化的时候,会把一些基础的provider调用起来,这些基础provider又调用了自身的初始化函数,来实现了一些自动化功能。
 
在public/index.php文件内,laravel首先加载了autoload方法,似乎是通过composer的方式实现的;
 
随后引入bootstrap/app.php文件,文件内实例化了application类,并通过该应用实例注册了Http、Kernel、Handler的共享绑定。
 
 
再看application类,继承自Container类,并继承了ApplicationContract接口(另一个application类,应该是实现了部分系统方法),与http核心接口(这里通过symfony的请求与响应类来实现接口)
 
插一张不知道从哪盗来的Application的继承关系图
 

在laravel把系统基础核心初始化完毕后,便通过application 的 make 方法,传入了http核心的类名来获取别名(在container类的aliases属性中,存储了众多类名与别名的键值对,似乎是通过类名到别名,再到实例的方式来获取的,数组见下方)

 container->aliases
=
array:64 [▼
"Illuminate\Foundation\Application" => "app"
"Illuminate\Contracts\Container\Container" => "app"
"Illuminate\Contracts\Foundation\Application" => "app"
"Psr\Container\ContainerInterface" => "app"
"Illuminate\Auth\AuthManager" => "auth"
"Illuminate\Contracts\Auth\Factory" => "auth"
"Illuminate\Contracts\Auth\Guard" => "auth.driver"
"Illuminate\View\Compilers\BladeCompiler" => "blade.compiler"
"Illuminate\Cache\CacheManager" => "cache"
"Illuminate\Contracts\Cache\Factory" => "cache"
"Illuminate\Cache\Repository" => "cache.store"
"Illuminate\Contracts\Cache\Repository" => "cache.store"
"Illuminate\Config\Repository" => "config"
"Illuminate\Contracts\Config\Repository" => "config"
"Illuminate\Cookie\CookieJar" => "cookie"
"Illuminate\Contracts\Cookie\Factory" => "cookie"
"Illuminate\Contracts\Cookie\QueueingFactory" => "cookie"
"Illuminate\Encryption\Encrypter" => "encrypter"
"Illuminate\Contracts\Encryption\Encrypter" => "encrypter"
"Illuminate\Database\DatabaseManager" => "db"
"Illuminate\Database\Connection" => "db.connection"
"Illuminate\Database\ConnectionInterface" => "db.connection"
"Illuminate\Events\Dispatcher" => "events"
"Illuminate\Contracts\Events\Dispatcher" => "events"
"Illuminate\Filesystem\Filesystem" => "files"
"Illuminate\Filesystem\FilesystemManager" => "filesystem"
"Illuminate\Contracts\Filesystem\Factory" => "filesystem"
"Illuminate\Contracts\Filesystem\Filesystem" => "filesystem.disk"
"Illuminate\Contracts\Filesystem\Cloud" => "filesystem.cloud"
"Illuminate\Contracts\Hashing\Hasher" => "hash"
"Illuminate\Translation\Translator" => "translator"
"Illuminate\Contracts\Translation\Translator" => "translator"
"Illuminate\Log\Writer" => "log"
"Illuminate\Contracts\Logging\Log" => "log"
"Psr\Log\LoggerInterface" => "log"
"Illuminate\Mail\Mailer" => "mailer"
"Illuminate\Contracts\Mail\Mailer" => "mailer"
"Illuminate\Contracts\Mail\MailQueue" => "mailer"
"Illuminate\Auth\Passwords\PasswordBrokerManager" => "auth.password"
"Illuminate\Contracts\Auth\PasswordBrokerFactory" => "auth.password"
"Illuminate\Auth\Passwords\PasswordBroker" => "auth.password.broker"
"Illuminate\Contracts\Auth\PasswordBroker" => "auth.password.broker"
"Illuminate\Queue\QueueManager" => "queue"
"Illuminate\Contracts\Queue\Factory" => "queue"
"Illuminate\Contracts\Queue\Monitor" => "queue"
"Illuminate\Contracts\Queue\Queue" => "queue.connection"
"Illuminate\Queue\Failed\FailedJobProviderInterface" => "queue.failer"
"Illuminate\Routing\Redirector" => "redirect"
"Illuminate\Redis\RedisManager" => "redis"
"Illuminate\Contracts\Redis\Factory" => "redis"
"Illuminate\Http\Request" => "request"
"Symfony\Component\HttpFoundation\Request" => "request"
"Illuminate\Routing\Router" => "router"
"Illuminate\Contracts\Routing\Registrar" => "router"
"Illuminate\Contracts\Routing\BindingRegistrar" => "router"
"Illuminate\Session\SessionManager" => "session"
"Illuminate\Session\Store" => "session.store"
"Illuminate\Contracts\Session\Session" => "session.store"
"Illuminate\Routing\UrlGenerator" => "url"
"Illuminate\Contracts\Routing\UrlGenerator" => "url"
"Illuminate\Validation\Factory" => "validator"
"Illuminate\Contracts\Validation\Factory" => "validator"
"Illuminate\View\Factory" => "view"
"Illuminate\Contracts\View\Factory" => "view"
]
 
http_kernel 的 bings属性为container容器所绑定
kernel obj的回调函数为容器自身所创建,在创建过程中,将一些回调函数进行绑定,并触发,但在index页面第一次初始化时,并没有回调函数被绑定触发,obj创建的过程还是不清楚。创建出的kernel对象里存储的是系统初始化所需的各种中间件与服务供应者的类名全称,见下方
index文件返回的kernel核心只是app/http/kernel的对象。而kernel核心在实例化时,依赖了application与route两个对象。并将自身的$middlewareGroups、routeMiddleware数组解析进了route对象里,在路由进行调用的时候就会把路由方法上绑定的中间件名在这里解析出实例来调用了,其中routeMiddleware为别名所用。
在创建出kernel实例后,通过其父类的handle方法加载了provider的基类,其加载了bootstrap引导函数。
依次执行$bootstrappers中每一个bootstrapper的bootstrap()函数 
$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',
];
上面bootstrap中会分别执行每一个bootstrapper的bootstrap方法来引导启动应用程序的各个部分
 
1. DetectEnvironment 检查环境
2. LoadConfiguration 加载应用配置
3. ConfigureLogging 配置日至
4. HandleException 注册异常处理的Handler
5. RegisterFacades 注册Facades
6. RegisterProviders 注册Providers
7. BootProviders 启动Providers
 
启动应用程序的最后两步就是注册服务提供者和启动提供者,先来看注册服务提供器,服务提供器的注册由类\Illuminate\Foundation\Bootstrap\RegisterProviders::class负责,该类用于加载所有服务提供器的 register 函数,并保存延迟加载的服务的信息,以便实现延迟加载。
 
所有服务提供器都在配置文件 app.php 文件的 providers 数组中。类 ProviderRepository 负责所有的服务加载功能:
loadManifest()会加载服务提供器缓存文件services.php,如果框架是第一次启动时没有这个文件的,或者是缓存文件中的providers数组项与config/app.php里的providers数组项不一致都会编译生成services.php。
 
Illuminate\Foundation\Http\Kernel 的 dispatchToRouter 方法返回的闭包函数里包含了调用请求的代码。这段代码指向了Illuminate\Routing\router类
 
Illuminate\Routing\Route类的runCallable方法里对路由进行了调用
 
控制器和方法是从路由文件中获取到的(通过symfony的request对象获取到pathinfo),依然是通过字符串解析为类名和方法名,随后通过ioc容器实例化类为对象,再调用控制器基类的某个方法执行传入的方法名
 
Illuminate\Routing\ControllerDispatcher类的dispatch方法为真正执行的部分
 
插一张流程图
 

laravel5.5源码阅读草稿——入口的更多相关文章

  1. laravel5.5源码阅读草稿——路由

    laravel 里的路由是由RouteServiceProvider提供的,其中的boot方法为启动项,调用了父类的boot方法. RouteServiceProvider中的boot方法设置了自己与 ...

  2. laravel5.5源码阅读草稿——application

    构建方法传入整个项目根目录路径(public文件夹上一级)将其设为基础路径(存在本类basePath属性中). __construct > setBasePath > bindPathsI ...

  3. CI框架源码阅读笔记2 一切的入口 index.php

    上一节(CI框架源码阅读笔记1 - 环境准备.基本术语和框架流程)中,我们提到了CI框架的基本流程,这里再次贴出流程图,以备参考: 作为CI框架的入口文件,源码阅读,自然由此开始.在源码阅读的过程中, ...

  4. CI框架源码阅读笔记4 引导文件CodeIgniter.php

    到了这里,终于进入CI框架的核心了.既然是“引导”文件,那么就是对用户的请求.参数等做相应的导向,让用户请求和数据流按照正确的线路各就各位.例如,用户的请求url: http://you.host.c ...

  5. CI框架源码阅读笔记3 全局函数Common.php

    从本篇开始,将深入CI框架的内部,一步步去探索这个框架的实现.结构和设计. Common.php文件定义了一系列的全局函数(一般来说,全局函数具有最高的加载优先权,因此大多数的框架中BootStrap ...

  6. CI框架源码阅读笔记1 - 环境准备、基本术语和框架流程

    最开始使用CI框架的时候,就打算写一个CI源码阅读的笔记系列,可惜虎头蛇尾,一直没有行动.最近项目少,总算是有了一些时间去写一些东西.于是准备将之前的一些笔记和经验记录下来,一方面权作备忘,另一方面时 ...

  7. Spring源码阅读系列总结

    最近一段时间,粗略的查看了一下Spring源码,对Spring的两大核心和Spring的组件有了更深入的了解.同时在学习Spring源码时,得了解一些设计模式,不然阅读源码还是有一定难度的,所以一些重 ...

  8. 39 网络相关函数(七)——live555源码阅读(四)网络

    39 网络相关函数(七)——live555源码阅读(四)网络 39 网络相关函数(七)——live555源码阅读(四)网络 简介 14)readSocket从套接口读取数据 recv/recvfrom ...

  9. 转-OpenJDK源码阅读导航跟编译

    OpenJDK源码阅读导航 OpenJDK源码阅读导航 博客分类: Virtual Machine HotSpot VM Java OpenJDK openjdk 这是链接帖.主体内容都在各链接中.  ...

随机推荐

  1. drag与drop事件

    为了支持网页上一些元素的拖动效果,可以使用drag和drog事件. 目前ie 5.0+, firefox 3.5+等都支持这些事件,ECMA Script第5版正式将其纳入标准. 对于被拖动的元素来说 ...

  2. js 获取 网页屏幕高度 窗口高度 元素高度 滚动高度

    常用: JS 获取浏览器窗口大小 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 // 获取窗口宽度 if (window.innerWidth) winWidth = ...

  3. vim的visual模式

    在可视化模式下,可以对一个文本块的整体进行操作.例如,首先高亮选中一部分文本,然后用d命令删除这个文本块.可视化模式的好处在于,你可以在做改动之前,就看到操作将影响的文本.可视化模式可以分为以下三种: ...

  4. 基于NFS实现多WEB服务器负载均衡

    实现环境: 实现原理: 共四台服务器 A,B,C,D 服务器A (CentOS 6.7): IP地址: 192.168.3.67 角色: DNS服务 说明: 为两台web服务器做域名轮询 服务器B,C ...

  5. g++: error: unrecognized command line option ‘-std=C++11’

    一个小程序,在编译的时候出错,原来使用的编译命令是 g++ -std=C++11 array.cpp -o array.exe g++: error: unrecognized command lin ...

  6. July 04th 2017 Week 27th Tuesday

    Nothing is really beautiful but truth. 只有真理才是真美. Truth can be beautiful, but it also can be cruel. W ...

  7. 如何在Windows中安装GitHub

    1.使用Git 在Git官网下载Git安装包,双击开始安装即可.安装完毕之后,在Windows中会具有一个Git Bash命令行工具以及一个Git GUI客户端工具. 点击Download即可下载. ...

  8. Radmin自动连接 c#版 带源码

    实现原理:1.利用radminview 自带命令 2.大漠绑定插件. 附图: 源码下载:http://files.cnblogs.com/eastday/Radmin%E8%87%AA%E5%8A%A ...

  9. 51nod 1832 先序遍历与后序遍历【二叉树+高精度】

    题目链接:51nod 1832 先序遍历与后序遍历 基准时间限制:1 秒 空间限制:131072 KB 分值: 40 难度:4级算法题 对于给定的一个二叉树的先序遍历和后序遍历,输出有多少种满足条件的 ...

  10. hdu-2886 Special Prime---数论推导

    题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=2866 题目大意: 问你1到L中有多少个素数满足n^3 + p*n^2 = m^3(其中n,m为大于1 ...