Laravel修炼:服务提供者

前言

  上一篇博客文章收集了关于Laravel服务容器的相关知识(传送门),咱们知道了服务容器主要有绑定和解析两个重要功能,那么Laravel这个框架集齐了如此多功能,咱们项目可能还须要另外引入一些功能包,这些绑定必须有一个统一的管理工具,统一绑定在一个地方,这个地方就是服务提供者。php

关于服务提供者

  一开始学Laravel被服务容器和服务提供者两个名称搞混了,其实如今我是这样理解:容器就是底层一个大桶, 咱们须要不少材料往里面填充,而提供者就是一些管道,咱们就是经过提供者往容器里面塞咱们须要的东西,须要的服务。html

  Laravel有一种机制来定义和执行每一个服务的初始处理,实现初始处理的类称为服务提供者laravel

  服务提供者,在laravel里面,其实就是一个工厂类。它最大的做用就是用来进行服务绑定。当咱们须要绑定一个或多个服务的时候,能够自定义一个服务提供者,而后把服务绑定的逻辑都放在该类的实现中。在larave里面,要自定一个服务提供者很是容易,只要继承IlluminateSupportServiceProvider这个类便可。下面经过一个简单的自定义服务提供者来讲明服务提供者的一些要点:git

<?php

namespace App\Providers;

use Illuminate\Support\ServiceProvider;

class yourServiceProvider extends ServiceProvider
{
    protected $defer = true;

    public function boot()
    {
        //
    }

    public function register()
    {
        $this->app->singleton('service1', function(){
            return 'service1';
        });
        $this->app->singleton('service2', function(){
            return 'service2';
        });
        $this->app->singleton('service3', function(){
            return 'service3';
        });
    }

    public  function provides()
    {
        return ['service1','service2','service3'];
    }
}

对于服务提供者类能够经过artisan命令建立:github

artisan make:provider yourServiceProvider

建立后的文件会存放在appProviders目录下bootstrap

avatar

  如今咱们的服务已经在yourServiceProvider这个类里面的register()里面进行绑定了。虽然完成了服务提供者的建立和绑定,但框架如今不知道多了一个服务提供者,因此在程序运行过程当中还不会调用该类中的registe()方法,因此须要在某个位置进行注册来告诉框架新建立的服务提供者--配置文件config/app.php缓存

'providers' => [

        /*
         * Laravel Framework Service Providers...
         */
        Illuminate\Auth\AuthServiceProvider::class,
        Illuminate\Broadcasting\BroadcastServiceProvider::class,
        Illuminate\Bus\BusServiceProvider::class,
        Illuminate\Cache\CacheServiceProvider::class,
        Illuminate\Foundation\Providers\ConsoleSupportServiceProvider::class,
        ...
        ...
        ...
        App\Providers\AppServiceProvider::class,
        App\Providers\AuthServiceProvider::class,
        // App\Providers\BroadcastServiceProvider::class,
        App\Providers\EventServiceProvider::class,
        App\Providers\RouteServiceProvider::class,

    ],

当laravel找到这个服务提供者的类之后,就会初始化这个服务提供者类,获得一个服务提供者的对象,而后调用它的register方法,天然它里面的全部服务绑定代码就都会执行了:app

public function registerConfiguredProviders()
    {
        $manifestPath = $this->getCachedServicesPath();

        (new ProviderRepository($this, new Filesystem, $manifestPath))
                    ->load($this->config['app.providers']);
    }

laravel会把全部的自定义服务提供者都注册进来。这个注册的过程其实就是前面说的实例化服务提供者的类,并调用register方法的过程。composer

  除了register方法,服务提供者里面还有一个boot方法,这个boot方法,会在全部的服务提供者都注册完成以后才会执行,因此当你想在服务绑定完成以后,经过容器解析出其它服务,作一些初始化工做的时候,那么就能够这些逻辑写在boot方法里面。由于boot方法执行的时候,全部服务提供者都已经被注册完毕了,因此在boot方法里面可以确保其它服务都能被解析出来。框架

  以上主要介绍了laravel服务提供器的做用和具体使用方法,在咱们平时的开发通常状况下引入第三方包就是这样的步骤(举例overtrue/laravel-wechat):

  • 安装引入:composer require "overtrue/laravel-wechat:~4.0"
  • 在 config/app.php 注册 ServiceProvider 和 Facade(Laravel 5.5 无需手动注册)
'providers' => [
    // ...
    Overtrue\LaravelWeChat\ServiceProvider::class,
],
'aliases' => [
    // ...
    'EasyWeChat' => Overtrue\LaravelWeChat\Facade::class,
],
  • 建立配置文件
artisan vendor:publish --provider="Overtrue\LaravelWeChat\ServiceProvider
服务提供者还有一个小问题值的注意,因为php是一门基本语言,在处理请求的时候,都会从入口文件把全部php都执行一遍。为了性能考虑,laravel会在第一次初始化的时候,把全部的服务提供者都缓存到bootstrap/cache/services.php文件里面,因此有时候当你改了一个服务提供者的代码之后,再刷新不必定能看到指望的效果,这有可能就是由于缓存所致。这时把services.php删掉就能看到你要的效果了。

 再次感 云诸葛这篇文章,看完后收货很大,本文内容较为粗略,想要详细了解能够看这里laravel框架容器管理的一些要点

相关文章
相关标签/搜索