[TOC]
## 1、簡介
[服務提供者](http://laravelacademy.org/tags/%e6%9c%8d%e5%8a%a1%e6%8f%90%e4%be%9b%e8%80%85 "View all posts in 服務提供者")是所有[Lumen](http://laravelacademy.org/tags/lumen "View all posts in Lumen")應用啟動的中心,你自己的應用以及所有Lumen的核心服務都是通過服務提供者啟動。
但是,我們所謂的”啟動“指的是什么?通常,這意味著[注冊](http://laravelacademy.org/tags/%e6%b3%a8%e5%86%8c "View all posts in 注冊")事物,包括注冊[服務容器](http://laravelacademy.org/tags/%e6%9c%8d%e5%8a%a1%e5%ae%b9%e5%99%a8 "View all posts in 服務容器")綁定、時間監聽器、中間件甚至路由。服務提供者是應用配置的中心。
如果你打開Lumen自帶的`bootstrap/app.php`文件,將會看到一個`$app->register(`)調用,這里就是應用所要加載的所有服務提供者類。
本章里你將會學習如何編寫自己的服務提供者并在Lumen應用中注冊它們。
## 2、編寫服務提供者
所有的服務提供者繼承自`Illuminate\Support\ServiceProvider`類。繼承該抽象類要求至少在服務提供者中定義一個方法:`register`。在`register`方法內,你唯一要做的事情就是綁事物到[服務容器](http://laravelacademy.org/post/471.html),不要嘗試在其中注冊任何時間監聽器,路由或者任何其它功能。
#### 2.1 register方法
正如前面所提到的,在`register`方法中只綁定事物到[服務容器](http://laravelacademy.org/post/471.html),而不要做其他事情,否則話,一不小心就能用到一個尚未被加載的服務提供者提供的服務。
現在讓我們來看看一個基本的服務提供者長什么樣:
~~~
<?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`的實現。如果你不太理解服務容器是怎么工作的,查看其[文檔](http://laravelacademy.org/post/471.html)。
#### 2.2 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()
{
//
}
}
~~~
## 3、注冊服務提供者
所有服務提供者都是通過配置文件`bootstrap/app.php`中進行注冊,該文件包含了一個`$app->register()`方法調用,你可以將自己自定義的服務提供者放到該方法調用中來注冊服務提供者。