内容简介:服务提供者是 Laravel 应用启动的中心,你自己的应用以及所有 Laravel 的核心服务都是通过服务提供者启动。但是,我们所谓的「启动」指的是什么?通常,这意味着注册服务,包括注册服务容器绑定、事件监听器、中间件甚至路由。服务提供者是应用配置的中心。如果你打开 Laravel 自带的
简介
服务提供者是 Laravel 应用启动的中心,你自己的应用以及所有 Laravel 的核心服务都是通过服务提供者启动。
但是,我们所谓的「启动」指的是什么?通常,这意味着注册服务,包括注册服务容器绑定、事件监听器、中间件甚至路由。服务提供者是应用配置的中心。
如果你打开 Laravel 自带的 config/app.php
文件,将会看到一个 providers
数组,这里就是应用所要加载的所有服务提供者类,当然,其中很多是延迟加载的,也就是说不是每次请求都会被加载,只有真的用到它们的时候才会加载。
通过本文档,你将会学习如何编写自己的服务提供者并在 Laravel 应用中注册它们。
编写服务提供者
所有的服务提供者都继承自 Illuminate\Support\ServiceProvider
类。大部分服务提供者都包含两个方法: register
和 boot
。在 register
方法中,你唯一要做的事情就是绑定服务到服务容器,不要尝试在该方法中注册事件监听器,路由或者任何其它功能。
通过 Artisan 命令 make:provider
即可生成一个新的提供者:
php artisan make:provider RiakServiceProvider
register 方法
正如前面所提到的,在 register
方法中只绑定服务到服务容器,而不要做其他事情,否则,一不小心就可能用到一个尚未被加载的服务提供者提供的服务。
现在让我们来看看一个基本的服务提供者长什么样,在任何服务提供者方法中,都可以通过 $app
属性来访问服务容器:
<?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
的实现。如果你不知道服务容器是如何工作的,请参考其文档。
bindings
和 singletons
属性
如果你的服务提供者注册了很多简单的绑定,你可能希望使用 bindings
和 singletons
属性来替代手动注册每个容器绑定以简化代码。当服务提供者被框架加载后,会自动检查这些属性并注册相应绑定:
<?php namespace App\Providers; use App\Contracts\ServerProvider; use App\Contracts\DowntimeNotifier; use Illuminate\Support\ServiceProvider; use App\Services\PingdomDowntimeNotifier; use App\Services\DigitalOceanServerProvider; class AppServiceProvider extends ServiceProvider { /** * All of the container bindings that should be registered. * * @var array */ public $bindings = [ ServerProvider::class => DigitalOceanServerProvider::class, ]; /** * All of the container singletons that should be registered. * * @var array */ public $singletons = [ DowntimeNotifier::class => PingdomDowntimeNotifier::class, ]; }
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 方法的依赖注入
我们可以在 boot
方法中对依赖进行类型提示,服务容器会自动注入你所需要的依赖:
use Illuminate\Contracts\Routing\ResponseFactory; public function boot(ResponseFactory $response){ $response->macro('caps', function ($value) { // }); }
注册服务提供者
所有服务提供者都是通过配置文件 config/app.php
中进行注册,该文件包含了一个列出所有服务提供者名字的 providers
数组,默认情况下,其中列出了所有核心服务提供者,这些服务提供者启动 Laravel核心组件,比如邮件、队列、缓存等等。
要注册你自己的服务提供者,只需要将其追加到该数组中即可:
'providers' => [ // 其它服务提供者 App\Providers\ComposerServiceProvider::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]; } }
注:强烈推荐阅读 深入理解控制反转(IoC)和依赖注入(DI) 深入理解服务容器和服务提供者的实现原理。
以上所述就是小编给大家介绍的《[ Laravel 5.7 文档 ] 底层原理 —— 服务提供者》,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对 码农网 的支持!
猜你喜欢:- Laravel初级教程之服务提供者
- Laravel创建服务器提供者实例
- 干货 | 研究以太坊 2.0 中的状态提供者模型
- Laravel Providers——服务提供者的注册与启动源码解析
- 服务提供者(provider)与服务消费者(ribbon版本)-微服务架构
- 创新中关村报道称 Cocos 开发者沙龙为开发者、技术提供者等提供了交流合作平台
本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。
UML基础、案例与应用
施穆勒 / 李虎、赵龙刚 / 人民邮电出版社 / 2004-7-1 / 42.00元
本书教读者循序渐进地、系统地学习UML基础知识和应用技术。和前一版相比,本书内容根据UML 2.0进行了补充和更新,随书光盘包含了建模工具Poseidon的试用版。 全书分为三部分24章。第一部分“基础知识”包括第1章到第15章,主要是介绍UML语言的基础知识以及面向对象的概念和思想,还简单介绍了UML在开发过程的应用方法。第二部分“学习案例”包括第16章到第22章,结合实例详细分析了UML的应用......一起来看看 《UML基础、案例与应用》 这本书的介绍吧!
在线进制转换器
各进制数互转换器
HTML 编码/解码
HTML 编码/解码