思考并回答以下问题:
简介
服务提供者是Laravel应用启动的中心,你自己的应用以及所有Laravel的核心服务都是通过服务提供者启动。
但是,我们所谓的「启动」指的是什么?通常,这意味着注册服务,包括注册服务容器绑定、事件监听器、中间件甚至路由。服务提供者是应用配置的中心。
如果你打开Laravel自带的config/app.php文件,将会看到一个providers数组,这里就是应用所要加载的所有服务提供者类,当然,其中很多是延迟加载的,也就是说不是每次请求都会被加载,只有真的用到它们的时候才会加载。
通过本文档,你将会学习如何编写自己的服务提供者并在Laravel应用中注册它们。
编写服务提供者
所有的服务提供者都继承自Illuminate\Support\ServiceProvider类。大部分服务提供者都包含两个方法:register和boot。在register方法中,你唯一要做的事情就是绑定服务到服务容器,不要尝试在该方法中注册事件监听器,路由或者任何其它功能。
通过Artisan命令make:provider即可生成一个新的提供者:
1 | php artisan make:provider RiakServiceProvider |
register方法
正如前面所提到的,在register方法中只绑定服务到服务容器,而不要做其他事情,否则,一不小心就可能用到一个尚未被加载的服务提供者提供的服务。
现在让我们来看看一个基本的服务提供者长什么样,在任何服务提供者方法中,都可以通过$app属性来访问服务容器:
1 |
|
该服务提供者只定义了一个register方法,并使用该方法在服务容器中定义了一个Riak\Connection的实现。如果你不知道服务容器是如何工作的,请参考其文档。
bindings和singletons属性
如果你的服务提供者注册了很多简单的绑定,你可能希望使用bindings和singletons属性来替代手动注册每个容器绑定以简化代码。当服务提供者被框架加载后,会自动检查这些属性并注册相应绑定:
1 |
|
boot方法
如果我们想要在服务提供者中注册视图Composer该怎么做?这就要用到boot方法了。该方法在所有服务提供者被注册以后才会被调用,这就是说我们可以在其中访问框架已注册的所有其它服务:
1 |
|
boot方法的依赖注入
我们可以在boot方法中对依赖进行类型提示,服务容器会自动注入你所需要的依赖:
1 | use Illuminate\Contracts\Routing\ResponseFactory; |
注册服务提供者
所有服务提供者都是通过配置文件config/app.php中进行注册,该文件包含了一个列出所有服务提供者名字的providers数组,默认情况下,其中列出了所有核心服务提供者,这些服务提供者启动 Laravel核心组件,比如邮件、队列、缓存等等。
要注册你自己的服务提供者,只需要将其追加到该数组中即可:
1 | 'providers' => [ |
延迟加载服务提供者
如果你的提供者仅仅只是在服务容器中注册绑定,你可以选择延迟加载该绑定直到注册绑定的服务真的需要时再加载,延迟加载这样的一个提供者将会提升应用的性能,因为它不会在每次请求时都从文件系统加载。
Laravel编译并保存所有延迟服务提供者提供的服务及服务提供者的类名。然后,只有当你尝试解析其中某个服务时Laravel才会加载其服务提供者。
想要延迟加载一个提供者,需要实现\Illuminate\Contracts\Support\DeferrableProvider接口并定义一个provides方法,provides方法会返回通过服务提供者注册的服务容器绑定:
1 |
|
源码
Illuminate\Support\ServiceProvider.php
1 |
|