Laravel 5.5 底层原理:服务提供者

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/lamp_yang_3533/article/details/85806701

简介

服务提供者(Provider)是所有 Laravel 应用程序的引导中心。

你的应用程序以及 Laravel 的所有核心服务都是通过服务提供者进行引导。

在这里,我们说的「引导」其实是指注册,通常,这意味着注册服务,包括注册服务容器绑定、事件监听器、中间件甚至路由。

服务提供者是应用配置的中心。

config/app.php 文件中有一个 providers 数组。数组中的内容是应用所要加载的所有服务提供者。

当然,其中很多是延迟加载的,也就是说不是每次请求都会被加载,只有真的用到它们的时候才会加载。

通过本文档,你将会学习如何编写自己的服务提供者并在 Laravel 应用中注册它们。

创建服务提供者

所有的服务提供者都继承自 Illuminate\Support\ServiceProvider 类。

大部分服务提供者都包含两个方法: register 和 boot 。在 register 方法中,你唯一要做的事情就是绑定服务到服务容器,不要尝试在该方法中注册事件监听器,路由或者任何其它功能。

通过 Artisan 命令 make:provider 即可生成一个新的提供者:

php artisan make:provider RiakServiceProvider

服务提供者默认会存放在 app/Providers 目录中,如刚刚创建的 app/Providers/RiakServiceProvider.php 。

register() 方法

在 register 方法中只绑定服务到服务容器,而不要做其他事情,否则,一不小心就可能用到一个尚未被加载的服务提供者提供的服务。

让我们来看一个基本的服务提供者。

<?php

namespace App\Providers;

use Riak\Connection;
use Illuminate\Support\ServiceProvider;

class RiakServiceProvider extends ServiceProvider
{
    /**
     * 在容器中注册绑定。
     *
     * @return void
     */
    public function register()
    {
        $this->app->singleton(Connection::class, function ($app) {
            return new Connection(config('riak'));
        });
    }
}

该服务提供者只定义了一个 register 方法,并使用该方法在服务容器中定义了一个 Riak\Connection 的实现。

boot() 方法

如果我们想要在服务提供者中注册视图 composer 该怎么做?这就要用到 boot 方法了。

boot 方法会在所有的服务提供者被注册后自动调用,这意味着可以在其中访问框架已注册的所有其它服务。

<?php

namespace App\Providers;

use Illuminate\Support\ServiceProvider;

class ComposerServiceProvider extends ServiceProvider
{
    /**
     * 引导任何应用程序服务。
     *
     * @return void
     */
    public function boot()
    {
        view()->composer('view', function () {
            //
        });
    }
}

boot() 方法的依赖注入

可以在 boot 方法中对依赖进行类型提示,服务容器会自动注入你所需要的依赖:

use Illuminate\Contracts\Routing\ResponseFactory;

public function boot(ResponseFactory $response)
{
    $response->macro('caps', function ($value) {
        //
    });
}

注册服务提供者

几乎所有的服务提供者都是通过配置文件 config/app.php 中的 providers 数组进行注册。

默认情况下,providers 数组列出了所有核心服务提供者,这些服务提供者启动 Laravel核心组件,比如邮件、队列、缓存等等。

要注册你自己的服务提供者,只需将其追加到该数组中即可:

'providers' => [
    // 其他服务提供者

    App\Providers\ComposerServiceProvider::class,
],

需要说明的是,开发环境中专用的服务提供者,不要在 config/app.php 中注册。而是在 app/Providers/AppServiceProvider.php 中注册,以便灵活控制服务的加载。

public function register()
{
    if ($this->app->environment() !== 'production') {
        $this->app->register(\Barryvdh\LaravelIdeHelper\IdeHelperServiceProvider::class);
    }
    // ...
}

对于开发环境中专用的服务,推荐使用这种方式注册,因为它只会在非生产环境中加载。

延迟加载服务提供者

如果你的提供者仅仅只是在服务容器中注册绑定,你可以选择延迟加载该绑定直到注册绑定的服务真的需要时再加载,延迟加载这样的一个提供者将会提升应用的性能,因为它不会在每次请求时都从文件系统加载。

Laravel 编译并保存所有延迟服务提供者提供的服务及服务提供者的类名。然后,只有当你尝试解析其中某个服务时 Laravel 才会加载其服务提供者。

想要延迟加载一个服务提供者,需设置 defer 属性为 true 并定义一个 provides 方法,该方法返回该提供者注册的服务容器绑定。

<?php

namespace App\Providers;

use Riak\Connection;
use Illuminate\Support\ServiceProvider;

class RiakServiceProvider extends ServiceProvider
{
    /**
     * 是否延迟加载
     *
     * @var bool
     */
    protected $defer = true;

    /**
     * 注册服务提供者
     *
     * @return void
     */
    public function register()
    {
        $this->app->singleton(Connection::class, function ($app) {
            return new Connection($app['config']['riak']);
        });
    }

    /**
     * 获取提供者提供的服务。
     *
     * @return array
     */
    public function provides()
    {
        return [Connection::class];
    }

}

猜你喜欢

转载自blog.csdn.net/lamp_yang_3533/article/details/85806701
今日推荐