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框架容器管理的一些要點

相關文章
相關標籤/搜索