如何创建 Laravel 延迟加载的服务提供者

服务提供者

laravel 的服务提供者是建立在服务容器之上,实现高内聚、低耦合的功能模块。其中 register 函数负责将实现类绑定到服务容器中, boot 函数在所有服务容器注册完成之后执行,处理配置等一系列操作。

在 laravel 系统框架启动阶段,会读取配置文件 config/app.php 中 $providers 的所有需要加载的服务提供者,在所有服务提供者的 register 函数调用完成之后,再依次调用各个服务提供者的 boot 函数,完成服务提供者的注册和启动。所以不要尝试在 register 方法中注册任何监听器,路由,或者其他任何功能。否则,你可能会意外地使用到尚未加载的服务提供者提供的服务。

创建一个服务容器

创建一个接口类 和 一个对应的实现类


namespace App\Lufeijun1234\Provider\Contracts;

interface CurlContract
{
  public function get($url);
  public function post($url,$data,$header=[]);
}
namespace App\Lufeijun1234\Provider\Curl;

use App\Lufeijun1234\Provider\Contracts\CurlContract;

class CurlService implements CurlContract
{

  public function get($url)
  {
    echo "get";
  }

  public function post($url,$data,$header=[])
  {
    echo "post";
  }
}

执行的 artisan 命令

php artisan make:provider CurlServiceProvider

在 CurlServiceProvider 类中的 register 函数完成注册

public function register()
{
    echo "curl provider register<br>";
    $this->app->singleton('curl', function(){
      return new CurlService;
    });
}
public function boot()
{
    echo "curl provider boot<br>";
}

在 config/app.php 中注册服务提供者

直接在 providers 参数中新增 App\Providers\CurlServiceProvider::class,

验证

任意注册一个空的路由,通过页面访问,可以看到刚才在 register 和 boot 中写的输出语句打印出来,说明我们的服务提供者已经被注册和启动了,在 http 控制器中,通过 \App::make('curl') 便可以访问到我们新添加的服务提供者,进行 get|post 发送请求。

延迟服务提供者

如果系统在启动时加载的提供者过多,必然会导致系统性能下降,好在 laravel 框架为我们提供延迟加载服务提供者的功能,只有真正使用到改服务提供者时,才进行绑定和启动。

延迟服务提供者需要修改的地方

class CurlServiceProvider extends ServiceProvider 
{
  protected $defer = true;

  /**
   * 中间不变的地方暂时省略
   *
   */

  public function provides()
  {
    return ['curl'];
  }
}

利用框架的 artisan 命令生成缓存文件

执行 php artisan clear-compiled ,会重新生成框架缓存文件,在 bootstrap/cache/services.php 中保存系统服务提供者的所有信息,其中 deferred 保存的是所有需要延迟加载的服务提供者。

延迟加载注册启动逻辑

/**
 * vendor/laravel/framework/src/Illuminate/Foundation/Application.php
 * Resolve the given type from the container.
 *
 * (Overriding Container::make)
 *
 * @param  string  $abstract
 * @param  array  $parameters
 * @return mixed
 */
public function make($abstract, array $parameters = [])
{
    $abstract = $this->getAlias($abstract);

    if (isset($this->deferredServices[$abstract]) && ! isset($this->instances[$abstract])) {
        $this->loadDeferredProvider($abstract);
    }

    return parent::make($abstract, $parameters);
}

上边代码是系统服务容器解析实现类的逻辑,中间有一层判断,如果待解析的类在延迟加载服务提供者列表中,并且是首次解析时,便会调用延迟加载函数 loadDeferredProvider , 调用服务提供者的 register 和 boot 函数进行注册和绑定。之后在进行后续解析。

小结

通过对 laravel 框架服务提供者逻辑的理解,手动创建一个发送请求的 CurlServiceProvider 服务提供者,并且实现延迟加载,降低对框架系统性能的影响。如有不对,还请指教

本作品采用《CC 协议》,转载必须注明作者和本文链接
《L05 电商实战》
从零开发一个电商项目,功能包括电商后台、商品 & SKU 管理、购物车、订单管理、支付宝支付、微信支付、订单退款流程、优惠券等
《G01 Go 实战入门》
从零开始带你一步步开发一个 Go 博客项目,让你在最短的时间内学会使用 Go 进行编码。项目结构很大程度上参考了 Laravel。
讨论数量: 0
(= ̄ω ̄=)··· 暂无内容!

讨论应以学习和精进为目的。请勿发布不友善或者负能量的内容,与人为善,比聪明更重要!