欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

Laravel 服务提供者

程序员文章站 2022-06-13 20:21:46
...

理解服务提供者,需要有控制反转(IoC)和请求生命周期的基础。

控制反转

控制反转(IoC,Invension of Controller)是面向对象编程中的一种设计原则,用来减低代码之间的耦合度。其中最常见的方式叫做依赖注入(DI, Dependency Injection),还有一种叫做依赖查找(DL, Dependency Lookup)。

Laravel 服务提供者
控制反转

通过控制反转,对象在被创建的时,由一个调控系统内所有对象的外界实体,将其所依赖的对象的引用传递给它。也就是说,依赖被出入到对象中。

Laravel 服务提供者
依赖注入

简单来说,我们需要的是一个调控系统,调控系统存放对象实体或描述,在对象创建时将对象所依赖的对象引用传递过去。在Laravel中Service Container就是这个高效的调控系统,它是Larave的核心。

依赖注入

Laravel 服务提供者
依赖解耦

IoC(Inversion of Controller)控制反转模式,又称为依赖注入模式(DI, Dependency Injection)。理解控制反转就必须首先理解“依赖”的概念。

面向对象编程中,接口、类、对象之间的关系中,接口是类的原型,类必须遵守其实现的接口,对象则是类实例化的产物。这里延伸出一个重要的概念“依赖”。少量的依赖并不会有太过直接影响,当依赖达到一定量级时,那是怎样的一种噩梦呢?

简单来说,依赖就是“不是我自身的,却是我需要的,都是我所依赖的。一切需要外部提供的,都是需要进行 依赖注入的。”。

  • 依赖注入是由外部负责其依赖需求的行为
  • 依赖注入是将内部设计的类交给系统去控制,有些类在初始化时需特定的参数,当需要将实现类绑定到某个接口,此时必须对依赖进行配置,系统才能正确解析并引用。

大多数应用都是由多个类通过彼此合作来实现自身业务逻辑的,这使得每个对象都需要获取与其合作的对象(所依赖的对象)的引用。若这个获取过程要靠自身实现,那么将导致代码高度耦合并难以维护和调试。

Laravel 服务提供者
依赖解耦

依赖注入解决的问题

  • 依赖之间的解耦
  • 单元测试方便Mock

综上所述

  • 依赖注入是控制反转的一种实现,实现代码解耦,便于单元测试,因为它并不需要了解自身所依赖的类。而只需要知道所依赖的类实现了自身所需要的方法即可。
  • 控制反转提供了一种调控系统,实现依赖解析的自动注入,一般配合容器提供依赖对象实例的引用。

服务容器

Laravel的核心就是一个IoC容器(服务容器,Service Container),IoC容器提供整个框架中需要的服务。简单来说服务容器就是控制反转的容器,即一个调度系统。

对于容器,字面上的意思是装东西的器皿,编程中的容器如变量、对象属性都算是。一个容器能够容纳什么,取决于你对该容器的定义。

反射

服务容器需要通过反射(Reflection)来实现,那什么是反射呢?

编程中反射是指计算机在运行期间(runtime)可以访问、检测、修改它自身状态或行为的一种能力。简单来说就是程序能够观察并修改自己的行为。

支持反射的语言提供了一些在低级语言中难以实现的运行时特性

  • 作为一个第一类对象发现并修改源代码的结构,如代码块、类、方法、协议等。
  • 将跟class和function匹配的转换成class或function的调用或引用
  • 在运行时像对待源代码语句一样计算字符串
  • 创建一个新的语言的字节码解释器来给编程结构一个新的意义和用途

PHP实现的反射

反射是指在PHP运行状态中,扩展分析PHP程序,导出或提取出类、方法、属性、参数等详细数据,包括注释。这种动态获取信息以及动态调用对象方法的功能称为反射API。

反射是操作面向对象泛型中元模型的API,功能强大,可构建复杂且可扩展的应用,如自动加载插件,自动生成文档等。

服务提供者

ServiceProvider,按需加载服务的服务提供者。

在IoC容器中,一个类需要绑定、注册至容器中才能被“制造”。简单来说,一个类要被容器提取,就必须要先注册到容器。Laravel中这个容器就是服务容器(Service Container),我们需要某个服务,就得先注册然后绑定这个服务到容器,提供服务并绑定服务至容器的东西,就是服务提供者(Service Provider)。

虽然绑定一个类到容器不一定非要通过服务提供者。但是,有的类、模块会需要其他类和组件,为了保证初始化阶段不会出现所需模块和组件没有注册情况,Laravel将注册和初始化行为进行拆分,拆分后的产物就是现在的服务提供者。

从某种意义上说,服务提供者优点类似于HTTP控制器,HTTP控制器用于为相关路由注册提供统一管理,而服务提供者用于为相关服务容器提供统一的绑定场所,此外服务提供者还可以做一些初始化启动操作。

服务提供者主要分为两部分:注册(register)、引导或初始化(boot)。注册负责进行向容器注册脚本,但要注意祖册部分不要有对未知事物的依赖,如果有就要移步到引导部分中。

# app/Provider/AppServiceProvider.php
<?php
namespace App\Providers;
use Illuminate\Support\ServiceProvider;

class AppServiceProvider extends ServiceProvider
{
    public function boot()
    {
    }
    public function register()
    {
    }
}

Laravel每个核心组件都对应一个服务提供者,因此服务提供者是Laravel心脏而处于中心位置,是Laravel的核心。核心组件类在服务提供者这里完成注册、初始化以供后续调用。

  • 服务提供者是Laravel应用启动的中心位置
  • Laravel应用和核心服务都是通过服务提供者启动的
  • 服务提供者是配置应用的中心位置

服务提供者是配置应用的中心位置,应用开始时,去注册服务容器(ServiceContainer)、事件监听器、过滤器、路由等。

# config/app.php
'providers' => [
    Illuminate\Auth\AuthServiceProvider::class,
    /*
     * Application Service Providers...
     */
    App\Providers\AppServiceProvider::class,
    App\Providers\EventServiceProvider::class,
],

服务提供者工作流程

  1. 定义服务类
  2. 创建服务提供者
  3. 注册服务提供者
  4. 测试服务提供者