服務(wù)提供者

2018-12-17 10:43 更新

簡(jiǎn)介

服務(wù)提供者是所有 Laravel 應(yīng)用程序的啟動(dòng)中心。你的應(yīng)用程序,以及所有 Laravel 的核心服務(wù),都是透過(guò)服務(wù)提供者啟動(dòng)。

但我們所說(shuō)的「啟動(dòng)」指的是什么?一般而言,我們指注冊(cè)事物,包括注冊(cè)服務(wù)容器綁定、事件監(jiān)聽(tīng)器、過(guò)濾器,甚至路由。服務(wù)提供者是你的應(yīng)用程序配置中心所在。

如果你打開(kāi)包含于 Laravel 中的 config/app.php 這一文件,你會(huì)看到 providers 數(shù)組。這些是所有將加載至你的應(yīng)用程序里的服務(wù)提供者類。當(dāng)然,它們之中有很多屬于「緩載」提供者,意思是除非真正需要它們所提供的服務(wù),否則它們并不會(huì)在每一個(gè)請(qǐng)求中都被加載。

在這份概述中,你會(huì)學(xué)到如何編寫(xiě)你自己的服務(wù)提供者,并將它們注冊(cè)于你的 Laravel 應(yīng)用程序。

           

基本提供者例子

所有的服務(wù)提供者都應(yīng)繼承 Illuminate\Support\ServiceProvider 此一類。在這個(gè)抽象類中,至少必須定義一個(gè)方法: register 。在 register 方法中,應(yīng)該只綁定服務(wù)到服務(wù)容器之中。你永遠(yuǎn)不該試圖在 register 方法中注冊(cè)任何事件監(jiān)聽(tīng)器、路由或任何其他功能。

Artisan 命令行接口可以很容易地通過(guò) make:provider 產(chǎn)生新的提供者:

php artisan make:provider RiakServiceProvider

           

注冊(cè)者方法

現(xiàn)在,讓我們來(lái)看看基本的服務(wù)提供者:

<?php namespace App\Providers;use Riak\Connection;use Illuminate\Support\ServiceProvider;class RiakServiceProvider extends ServiceProvider {

    /**
     * 在容器中注冊(cè)綁定。
     *
     * @return void
     */
    public function register()
    {
        $this->app->singleton('Riak\Contracts\Connection', function($app)
        {
            return new Connection($app['config']['riak']);
        });
    }}

           

這個(gè)服務(wù)提供者只定義了一個(gè) register 方法,并在服務(wù)容器中使用此方法定義了一份 Riak\Contracts\Connection 的實(shí)現(xiàn)。若你還不了解服務(wù)容器是如何運(yùn)作的,不用擔(dān)心,我們很快會(huì)提到它。

此類位于 App\Providers 命名空間之下,因?yàn)檫@是 Laravel 中默認(rèn)服務(wù)提供者所在的位置。然而,你可以隨自己的需要改變它。你的服務(wù)提供者可被置于任何 Composer 能自動(dòng)加載的位置。

啟動(dòng)方法

所以,若我們需要在服務(wù)提供者中注冊(cè)一個(gè)事件監(jiān)聽(tīng)器,該怎么做?它應(yīng)該在 boot 方法中完成。這個(gè)方法會(huì)在所有的服務(wù)提供者注冊(cè)后才被調(diào)用,這能讓你使用框架中其他所有已注冊(cè)過(guò)的服務(wù)。

<?php namespace App\Providers;use Event;use Illuminate\Support\ServiceProvider;class EventServiceProvider extends ServiceProvider {

    /**
     * 執(zhí)行注冊(cè)后的啟動(dòng)服務(wù)。
     *
     * @return void
     */
    public function boot()
    {
        Event::listen('SomeEvent', 'SomeEventHandler');
    }

    /**
     * 在容器中注冊(cè)綁定。
     *
     * @return void
     */
    public function register()
    {
        //    }}

           

我們可以對(duì) boot 方法中的依賴作類型提示。服務(wù)容器會(huì)自動(dòng)注入任何你所需要的依賴:

use Illuminate\Contracts\Events\Dispatcher;public function boot(Dispatcher $events){
    $events->listen('SomeEvent', 'SomeEventHandler');}

           

           

注冊(cè)提供者

所有的服務(wù)提供者都在 config/app.php 此一配置文件中被注冊(cè)。此文件包含了一個(gè) providers 數(shù)組,你可以在其中列出你所有服務(wù)提供者的名稱。此數(shù)組默認(rèn)會(huì)列出一組 Laravel 的核心服務(wù)提供者。這些提供者啟動(dòng)了 Laravel 的核心組件,例如郵件發(fā)送者、隊(duì)列、緩存及其他等等。

要注冊(cè)你的提供者,只要把它加入此數(shù)組:

'providers' => [
    // 其他的服務(wù)提供者
    'App\Providers\AppServiceProvider',],

           

           

緩載提供者

若你的提供者僅僅用于綁定注冊(cè)到服務(wù)容器,你可以選擇延緩其注冊(cè),直到真正需要其中注冊(cè)的綁定才加載。延緩像這樣的提供者加載可增進(jìn)應(yīng)用程序的性能,因?yàn)檫@樣就不用每個(gè)請(qǐng)求都從文件系統(tǒng)中將其加載。

要延緩提供者加載,將 defer 性質(zhì)設(shè)為 true,并定義一個(gè) provides 方法。 provides 方法應(yīng)返回提供者所注冊(cè)的服務(wù)容器綁定。

<?php namespace App\Providers;use Riak\Connection;use Illuminate\Support\ServiceProvider;class RiakServiceProvider extends ServiceProvider {

    /**
     * 指定是否延緩提供者加載。
     *
     * @var bool
     */
    protected $defer = true;

    /**
     * 注冊(cè)服務(wù)提供者。
     *
     * @return void
     */
    public function register()
    {
        $this->app->singleton('Riak\Contracts\Connection', function($app)
        {
            return new Connection($app['config']['riak']);
        });
    }

    /**
     * 取得提供者所提供的服務(wù)。
     *
     * @return array
     */
    public function provides()
    {
        return ['Riak\Contracts\Connection'];
    }}

           

Laravel 編譯并保存所有由延緩服務(wù)提供者所提供的服務(wù)清單,以及其服務(wù)提供者的類名稱。只有在當(dāng)你嘗試解析其中的服務(wù)時(shí), Laravel 才會(huì)加載服務(wù)提供者。


以上內(nèi)容是否對(duì)您有幫助:
在線筆記
App下載
App下載

掃描二維碼

下載編程獅App

公眾號(hào)
微信公眾號(hào)

編程獅公眾號(hào)