服务提供者


简介

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

但我们所说的“启动”指的是什么?一般而言,我们指注册事物,包括注册服务容器绑定、事件监听器、过滤器,甚至路由。服务提供者是你的应用程序配置中心所在。

如果你打开包含于 Laravel 中的 config/app.php 这一文件,你会看到 providers 数组。这些是所有将加载至你的应用程序里的服务提供者类。当然,它们之中有很多属于“缓载”提供者,意思是除非真正需要它们所提供的服务,否则它们并不会在每一个请求中都被加载。

在这份概述中,你会学到如何编写你自己的服务提供者,并将它们注册于你的 Laravel 应用程序。

基本提供者例子

所有的服务提供者都应继承 Illuminate\Support\ServiceProvider 此一类。在这个抽象类中,至少必须定义一个方法: register 。在 register 方法中,应该只绑定服务到服务容器之中。你永远不该试图在 register 方法中注册任何事件监听器、路由或任何其他功能。

Artisan 命令行接口可以很容易地通过 make:provider 产生新的提供者:

  1. php artisan make:provider RiakServiceProvider

注册者方法

现在,让我们来看看基本的服务提供者:

  1. <?php namespace App\Providers;
  2. use Riak\Connection;
  3. use Illuminate\Support\ServiceProvider;
  4. class RiakServiceProvider extends ServiceProvider {
  5. /**
  6. * 在容器中注册绑定。
  7. *
  8. * @return void
  9. */
  10. public function register()
  11. {
  12. $this->app->singleton('Riak\Contracts\Connection', function($app)
  13. {
  14. return new Connection($app['config']['riak']);
  15. });
  16. }
  17. }

这个服务提供者只定义了一个 register 方法,并在服务容器中使用此方法定义了一份 Riak\Contracts\Connection 的实现。若你还不了解服务容器是如何运作的,不用担心,我们很快会提到它。

此类位于 App\Providers 命名空间之下,因为这是 Laravel 中默认服务提供者所在的位置。然而,你可以随自己的需要改变它。你的服务提供者可被置于任何 Composer 能自动加载的位置。

启动方法

所以,若我们需要在服务提供者中注册一个事件监听器,该怎么做?它应该在 boot 方法中完成。这个方法会在所有的服务提供者注册后才被调用,这能让你使用框架中其他所有已注册过的服务。

  1. <?php namespace App\Providers;
  2. use Event;
  3. use Illuminate\Support\ServiceProvider;
  4. class EventServiceProvider extends ServiceProvider {
  5. /**
  6. * 执行注册后的启动服务。
  7. *
  8. * @return void
  9. */
  10. public function boot()
  11. {
  12. Event::listen('SomeEvent', 'SomeEventHandler');
  13. }
  14. /**
  15. * 在容器中注册绑定。
  16. *
  17. * @return void
  18. */
  19. public function register()
  20. {
  21. //
  22. }
  23. }

我们可以对 boot 方法中的依赖作类型提示。服务容器会自动注入任何你所需要的依赖:

  1. use Illuminate\Contracts\Events\Dispatcher;
  2. public function boot(Dispatcher $events)
  3. {
  4. $events->listen('SomeEvent', 'SomeEventHandler');
  5. }

注册提供者

所有的服务提供者都在 config/app.php 此一配置文件中被注册。此文件包含了一个 providers 数组,你可以在其中列出你所有服务提供者的名称。此数组默认会列出一组 Laravel 的核心服务提供者。这些提供者启动了 Laravel 的核心组件,例如邮件发送者、队列、缓存及其他等等。

要注册你的提供者,只要把它加入此数组:

  1. 'providers' => [
  2. // 其他的服务提供者
  3. 'App\Providers\AppServiceProvider',
  4. ],

缓载提供者

若你的提供者仅仅用于绑定注册到服务容器,你可以选择延缓其注册,直到真正需要其中注册的绑定才加载。延缓像这样的提供者加载可增进应用程序的性能,因为这样就不用每个请求都从文件系统中将其加载。

要延缓提供者加载,将 defer 性质设为 true,并定义一个 provides 方法。 provides 方法应返回提供者所注册的服务容器绑定。

  1. <?php namespace App\Providers;
  2. use Riak\Connection;
  3. use Illuminate\Support\ServiceProvider;
  4. class RiakServiceProvider extends ServiceProvider {
  5. /**
  6. * 指定是否延缓提供者加载。
  7. *
  8. * @var bool
  9. */
  10. protected $defer = true;
  11. /**
  12. * 注册服务提供者。
  13. *
  14. * @return void
  15. */
  16. public function register()
  17. {
  18. $this->app->singleton('Riak\Contracts\Connection', function($app)
  19. {
  20. return new Connection($app['config']['riak']);
  21. });
  22. }
  23. /**
  24. * 取得提供者所提供的服务。
  25. *
  26. * @return array
  27. */
  28. public function provides()
  29. {
  30. return ['Riak\Contracts\Connection'];
  31. }
  32. }

Laravel 编译并保存所有由延缓服务提供者所提供的服务清单,以及其服务提供者的类名称。只有在当你尝试解析其中的服务时, Laravel 才会加载服务提供者。