美文网首页
Laravel 核心--服务提供者

Laravel 核心--服务提供者

作者: 伊Summer | 来源:发表于2017-08-12 14:22 被阅读132次

概述

在上一章我们了解,服务容器实现了 IOC 控制反转。为了实现这种控制反转,就需要绑定对象生成器的工作,在Laravel 中,服务提供者来实现这项工作的。 服务提供者Laravel 应用启动的中心,你自己的应用以及所有 Laravel 的核心服务都是通过服务提供者启动。 当然启动这些服务,需要加载注册服务,包括注册服务容器绑定、事件监听器、中间件甚至路由。服务提供者是应用配置的中心。

编写服务提供者

所有的服务提供者都继承自 Illuminate\Support\ServiceProvider 类。大部分服务提供者都包含两个方法: registerboot

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

php artisan make:provider RiakServiceProvider

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\Contracts\Connection的实现。如果你不知道服务容器是如何工作的,请参考服务容器

boot方法

如果我们想要在服务提供者中注册视图 composer 该怎么做?这就要用到 boot 方法了。该方法在所有服务提供者被注册以后才会被调用,这就是说我们可以在其中访问框架已注册的所有其它服务:

<?php

namespace App\Providers;

use Illuminate\Support\ServiceProvider;

class ComposerServiceProvider extends ServiceProvider{
    /**
     * Perform post-registration booting of services.
     *
     * @return void
     */
    public function boot()
    {
        view()->composer('view', function () {
            //
        });
    }
}

boot 方法在 register 方法之后调用,这就意味着,你无须担心在注入某个实例的时候,他还没有被绑定或实例化。

例如你建立了 SegmentFaultSegmentFaultApi 两个类,前者依赖与后者,但是在 register 中你不确定那个类先被实例化了,那么你可以在 boot 中再对后者进行引用,因为此时两个类都已经进行正确的配置。

boot方法的 依赖注入

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

use Illuminate\Contracts\Routing\ResponseFactory;

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

注册服务提供者

所有服务提供者都是通过配置文件 config/app.php 中进行注册,该文件包含了一个列出所有服务提供者名字的 providers 数组,默认情况下,其中列出了所有核心服务提供者,这些服务提供者启动 Laravel核心组件,比如邮件、队列、缓存等等。

你可以在该数组中进行添加注册提供者:

'providers' => [
 
        /*
         * Laravel 框架系统服务...
         */
        Illuminate\Auth\AuthServiceProvider::class,
        Illuminate\Broadcasting\BroadcastServiceProvider::class,
        Illuminate\Bus\BusServiceProvider::class,
        Illuminate\Cache\CacheServiceProvider::class,
        Illuminate\Foundation\Providers\ConsoleSupportServiceProvider::class,
        Illuminate\Cookie\CookieServiceProvider::class,
        Illuminate\Database\DatabaseServiceProvider::class,
        Illuminate\Encryption\EncryptionServiceProvider::class,
        Illuminate\Filesystem\FilesystemServiceProvider::class,
        Illuminate\Foundation\Providers\FoundationServiceProvider::class,
        Illuminate\Hashing\HashServiceProvider::class,
        Illuminate\Mail\MailServiceProvider::class,
        Illuminate\Notifications\NotificationServiceProvider::class,
        Illuminate\Pagination\PaginationServiceProvider::class,
        Illuminate\Pipeline\PipelineServiceProvider::class,
        Illuminate\Queue\QueueServiceProvider::class,
        Illuminate\Redis\RedisServiceProvider::class,
        Illuminate\Auth\Passwords\PasswordResetServiceProvider::class,
        Illuminate\Session\SessionServiceProvider::class,
        Illuminate\Translation\TranslationServiceProvider::class,
        Illuminate\Validation\ValidationServiceProvider::class,
        Illuminate\View\ViewServiceProvider::class,
 
        /*
         * Package Service Providers...
         */
 
        //
 
        /*
         *应用程序服务...
         */
        App\Providers\AppServiceProvider::class,
        App\Providers\AuthServiceProvider::class,
        // App\Providers\BroadcastServiceProvider::class,
        App\Providers\EventServiceProvider::class,
        App\Providers\RouteServiceProvider::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];
    }

}

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

相关文章

  • laravel 基础教程 —— 服务提供者

    简介 服务提供者是 laravel 应用启动的中心。你自己的应用以及 laravel 的核心服务都是通过服务提供者...

  • Laravel思维导图之Laravel核心概念

    Laravel 的核心概念包括:服务容器、服务提供者、门面(Facades)、契约(Contracts)。 服务容...

  • 1,前言

    Laravel核心关键字 依赖管理 composer 服务容器 service container 服务提供者 s...

  • Laravel 核心--服务提供者

    概述 在上一章我们了解,服务容器实现了 IOC 控制反转。为了实现这种控制反转,就需要绑定对象生成器的工作,在La...

  • laravel 服务提供者

    laravel ServiceProvider 服务提供者在app初始化注册进容器 ,每个服务提供者均继承基础的抽...

  • Laravel 中的一些概念

    laravel 中的一些概念 核心概念 容器:是运行依赖和注入的场所;几乎所有服务容器的绑定都是在服务提供者中进行...

  • 创建Laravel门面

    在laravel5中创建门面步骤 创建一个类文件. 将类型文件绑定到服务提供者 注册服务提供者为提供者到Confi...

  • laravel中服务提供者

    1 什么是服务提供者 服务提供者是所有 Laravel 应用程序的引导中心。你的应用程序,以及通过服务器引导的 L...

  • laravel 自定义服务提供者

    导语 laravel 的服务提供者,是框架的核心,提供了路由、日志、缓存等功能。这里要实现的需求是使用第三方 AP...

  • laravel容器是什么时候绑定服务提供者里面register的

    一直对服务提供者的原理也不会很明白了,今天特意去找了一下laravel在那里绑定服务提供者所提供的服务。 首先我们...

网友评论

      本文标题:Laravel 核心--服务提供者

      本文链接:https://www.haomeiwen.com/subject/yhgkrxtx.html