文字总是没有代码简明。这里只是将主要的类和流程进行记录,类似于目录或者地图的功能,不至于面对一堆源码的时候摸不到头绪。具体的实现细节还是要看代码。
核心概念
1、 Container
做两件事情。
- 绑定 bind()
将具体实现转为闭包,然后和接口对应起来,放在数组bindings中保存。 - 解析 make()
查询bindings,将接口的对应实现类找到,通过反射,将类实例化返回。通过ReflectionClass类实现。
2、Application
继承自Container,主要提供下面3个方法。
- bootstrap() 启动
依次调用7个Bootstrapper进行启动。 - register() 注册ServiceProvider
调用ServiceProvider的register()方法。 - boot()
将App的状态设为已经启动,调用ServiceProvider的boot()方法。
3、ServiceProvider
所有的功能都是以服务形式进行提供,例如:认证、权限、缓存、路由等。需要提供register()方法向Application注册,可提供boot()方法在Application启动后调用。
4、Contract
一堆接口,当你不知道一个类的主要作用的时候,可以看看其实现的接口。
5、Facade
给类起一个别名,方便调用。(ps:纯属增加复杂度,我更喜欢逻辑上的简单,不喜欢这种少打几个字母的方便)
6、 Bootstrapper
启动器,App也就是框架启动的过程。
一次请求的过程
// 初始化App,并启动
$app = new Application();
// 处理请求的核心类,关联路由
$kernel = new Kernel($app,$router);
// 将$_GET,$_POST等封装到$request里
$request = Request::capture();
// 根据路由找到对应函数处理请求,生成相应
$response = $kernel->handle($request);
$response->send(); // 发送响应
$kernel->terminate(); // 善后
Application的启动流程
首先,App初始化
- registerBaseBindings()
- registerBaseServiceProviders()
- registerCoreContainerAliases()
App启动,依次调用以下bootstrapper的bootstrap()方法,等到BootProviders启动后,依次再调用bootstrapper的boot()方法。
- DetectEnvironment 检测环境
- LoadConfiguration 加载设置
- ConfigureLogging 设置日志
- HandleExceptions 捕获异常
- RegisterFacades 注册Facade
- RegisterProviders 注册ServiceProvider
- BootProviders 启动ServiceProvider
下面重点分析后三个Bootstrapper
RegisterFacades()
将config/app.php
中的别名aliases进行注册。
通过spl_autoload_register
注册自动加载器,class_alias
方法注册别名。
通过注册别名,可以直接使用例如Route::get()
,Cache::get()
之类的方法,类加载器会自动找到对应的类的方法。
RegisterProviders()
将config/app.php
中的providers进行注册。ProviderRepository
会读取配置文件中的ServiceProvider,并会编译一份做为缓存,然后向App注册。
BootProviders()
调用各provider的boot()方法。
如何处理请求
路由是由RouteServiceProvider
进行提供,在App启动的过程中会调用Http/routes.php
文件,将路由放入RouteCollection
中。当有一个请求到来的时候Kernel
会匹配到对应的路由,然后调用相应的Controller
或者函数进行处理。Controller
会渲染模板或者其他的HTTP响应。
具体的框架核心部分也就这么多了。剩下的就是每个服务组件的实现细节问题了。