一、服务类的初始化
(1)在App类的初始化initialize方法中,对变量initializers进行了循环操作:
foreach ($this->initializers as $initializer) {
$this->make($initializer)->init($this);
}
数组initializers中保存了Error::class, RegisterService::class, BootService::class这三个元素,Error类是用来处理错误信息的,RegisterService和BootService就是用来注册和执行服务类的,都调用了每个元素的init方法
(2)在initialize方法中调用的load方法中,也要一段服务类的注册代码:
if (is_file($appPath . 'service.php')) {
$services = include $appPath . 'service.php';
foreach ($services as $service) {
$this->register($service);
}
}
将配置文件(app/service.php)中的服务类进行注册。
二、相关类和方法
RegisterService:注册服务类
成员变量:
services: 数组,保存需要注册的服务类
成员方法:
init:将数组services中的元素和配置文件(vendor/service.php)中的数据进行循环注册,调用App类的register方法(将数据添加到App类的属性services中)
BootService:启动服务类
成员方法:
init:直接调用App类的boot方法
App:容器类
成员方法:
register:注册服务,将服务保存到services中
(1)判断是否已经注册,如果是则返回
(2)字符串时,创建服务类对象
(3)如果服务类中有register方法,则执行
(4)如果有bind属性,则绑定服务类
(5)将服务类加入到services数组中
boot:启动服务,对services数组中的每个元素进行执行bootService方法
bootService:判断服务类中是否存在boot方法,如果存在则执行服务类中的这个方法
综上,服务类中的两个方法(register方法和boot方法)和一个变量(bind),都是可有可无,根据需要进行添加,一个是注册时调用,一个是启动时调用。
附:
配置文件
(1)app/service.php:App类的load方法中
(2)vendor/service.php:RegisterService类的init方法中(在这个流程中,中间件中加入了TraceDebug类,也就解释了thinkphp6框架中的公共类型的中间件中为什么有TraceDebug类)
model层,分页和验证功能全部使用了服务类的工作流程(RegisterService类中)