1、简介

服务提供者Laravel应用启动的中心,你自己的应用以及所有Laravel的核心服务都是通过服务提供者启动。

但是,我们所谓的“启动”指的是什么?通常,这意味着注册事物,包括注册服务容器绑定、事件监听器、中间件甚至路由。服务提供者是应用配置的中心。

如果你打开Laravel自带的config/app.php文件,将会看到一个providers数组,这里就是应用所要加载的所有服务提供者类,当然,其中很多是延迟加载的,也就是说不是每次请求都会被加载,只有真的用到它们的时候才会加载。

本章节里你将会学习如何编写自己的服务提供者并在Laravel应用中注册它们。

2、编写服务提供者

所有的服务提供者都继承自Illuminate\Support\ServiceProvider类。大部分服务提供者都包含两个方法:registerboot 。在register方法中,你唯一要做的事情就是绑事物到服务容器,不要尝试在其中注册事件监听器,路由或者任何其它功能。

通过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('Riak\Contracts\Connection', function ($app) {
return new Connection(config('riak'));
});
}
}

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

boot方法

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

<?php

namespace App\Providers;

use Illuminate\Support\ServiceProvider;

class EventServiceProvider extends ServiceProvider{
/**
* Perform post-registration booting of services.
*
* @return void
*/
public function boot()
{
view()->composer('view', function () {
//
});
} /**
* 在容器中注册绑定.
*
* @return void
*/
public function register()
{
//
}
}

boot方法的依赖注入

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

use Illuminate\Contracts\Routing\ResponseFactory;

public function boot(ResponseFactory $factory){
$factory->macro('caps', function ($value) {
//
});
}
3、注册服务提供者

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

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

'providers' => [
// 其它服务提供者
App\Providers\ComposerServiceProvider::class,
],
4、延迟加载服务提供者

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

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('Riak\Contracts\Connection', function ($app) {
            return new Connection($app['config']['riak']);
        });
    }
    /**
     * 获取由提供者提供的服务.
     *
     * @return array
     */
    public function provides()
    {
        return [Connection::class];
    }
}

核心概念 —— 服务提供者的更多相关文章

  1. laravel的核心概念:服务提供者provider解析

    我们知道laravel和核心就是一个IoC容器, 被称之为服务容器. 那么作为IoC容器, 就必须要有绑定对象生成器的工作.  在laravel中是服务提供者来项服务容器中绑定对象生成器的. 百牛信息 ...

  2. Eureka中的核心概念

    图片的链接出了一点小bug,导致图片不能正常访问,小伙伴们可以移步这里:https://mp.weixin.qq.com/s/kAqOTKUt_qPlxzI4aGS5Pw 本文是Spring Clou ...

  3. Laravel 核心概念

    工欲善其事,必先利其器.在开发Xblog的过程中,稍微领悟了一点Laravel的思想.确实如此,这篇文章读完你可能并不能从无到有写出一个博客,但知道Laravel的核心概念之后,当你再次写起Larav ...

  4. Laravel 的核心概念

    工欲善其事,必先利其器.在开发Xblog的过程中,稍微领悟了一点Laravel的思想.确实如此,这篇文章读完你可能并不能从无到有写出一个博客,但知道Laravel的核心概念之后,当你再次写起Larav ...

  5. dubbo入门学习(一)-----分布式基础理论、架构发展以及rpc、dubbo核心概念

    一.分布式基础理论 1.什么是分布式系统? <分布式系统原理与范型>定义: “分布式系统是若干独立计算机的集合,这些计算机对于用户来说就像单个相关系统” 分布式系统(distributed ...

  6. Angular核心概念之五---过滤器

    Filter:过滤器,用于在view中呈现数据时显示为另一种格式:过滤器的本质是一个函数,接收原始数据转换为新的格式进行输出: function(oldVal){ ... return newVal ...

  7. 领域驱动设计(DDD)部分核心概念的个人理解

    领域驱动设计(DDD)是一种基于模型驱动的软件设计方式.它以领域为核心,分析领域中的问题,通过建立一个领域模型来有效的解决领域中的核心的复杂问题.Eric Ivans为领域驱动设计提出了大量的最佳实践 ...

  8. Javascript本质第一篇:核心概念

    很多人在使用Javascript之前都至少使用过C++.C#或Java,面向对象的编程思想已经根深蒂固,恰好Javascript在语法上借鉴了Java,虽然方便了Javascript的入门,但要深入理 ...

  9. [程序设计语言]-[核心概念]-02:名字、作用域和约束(Bindings)

    本系列导航 本系列其他文章目录请戳这里. 1.名字.约束时间(Binding Time) 在本篇博文开始前先介绍两个约定:第一个是“对象”,除非在介绍面向对象语言时,本系列中出现的对象均是指任何可以有 ...

随机推荐

  1. c语言中register类型的变量

    C语言中: 一.register变量 关键字regiter请求编译器尽可能的将变量存在CPU的寄存器中.有以下几点注意的地方. register变量必须是能被CPU寄存器所接受的类型,这通常意味着re ...

  2. codeforces 622A Infinite Sequence

    A. Infinite Sequence time limit per test 1 second memory limit per test 256 megabytes input standard ...

  3. BestCoder Round #68 (div.2) geometry(hdu 5605)

    geometry Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others)Total Su ...

  4. [iOS UI进阶 - 6.2] 核心动画CoreAnimation 练习代码

    A.基本用法 1.CABasicAnimation // // ViewController.m // CoreAnimationTest // // Created by hellovoidworl ...

  5. linux下登陆用户的行为信息—w和who命令详解

    查看用户的操作系统管理员若想知道某一时刻用户的行为,只需要输入命令w 即可,在SHELL终端中输入如下命令: [root@localhost ~]# w 可以看到执行w命令及显示结果. 命令信息含义上 ...

  6. MySQL Update语句用法

    用一个表的某列值更新另外一个表的某列值的sql语句: update tableA a innner join tableB b on a.column_1 = b.column_1 set a.col ...

  7. word2007 每页显示表头

    word2007 每页显示表头 在Word 2007文档中,如果一张表格需要在多页中跨页显示,则设置标题行重复显示很有必要,因为这样会在每一页都明确显示表格中的每一列所代表的内容.在Word 2007 ...

  8. js字符串常用判断方法

    转自:http://blog.sina.com.cn/s/blog_6819fa800100j5t6.html 一.方法介绍 function obj$(id)                     ...

  9. Cocos2d-x——CocosBuilder官方帮助文档翻译3 动画

    Working with Animations 动画 You can use CocosBuilder for creating character animations, animating com ...

  10. Codeforces Gym 100286F Problem F. Fibonacci System 数位DP

    Problem F. Fibonacci SystemTime Limit: 20 Sec Memory Limit: 256 MB 题目连接 http://acm.hust.edu.cn/vjudg ...