laravel 的服務提供者是建立在服務容器之上,實現高內聚、低耦合的功能模組。其中 register 函式負責將實現類繫結到服務容器中, boot 函式在所有服務容器註冊完成之後執行,處理配置等一系列操作。
在 laravel 系統框架啟動階段,會讀取配置檔案 config/app.php 中 $providers 的所有需要載入的服務提供者,在所有服務提供者的 register 函式呼叫完成之後,再依次呼叫各個服務提供者的 boot 函式,完成服務提供者的註冊和啟動。所以不要嘗試在 register 方法中註冊任何監聽器,路由,或者其他任何功能。否則,你可能會意外地使用到尚未載入的服務提供者提供的服務。
建立一個服務容器
建立一個介面類 和 一個對應的實現類
namespace App\Lufeijun1234\Provider\Contracts;
interface CurlContract
{
public function get($url);
public function post($url,$data,$header=[]);
}
namespace App\Lufeijun1234\Provider\Curl;
use App\Lufeijun1234\Provider\Contracts\CurlContract;
class CurlService implements CurlContract
{
public function get($url)
{
echo "get";
}
public function post($url,$data,$header=[])
{
echo "post";
}
}
執行的 artisan 命令
php artisan make:provider CurlServiceProvider
在 CurlServiceProvider 類中的 register 函式完成註冊
public function register()
{
echo "curl provider register<br>";
$this->app->singleton('curl', function(){
return new CurlService;
});
}
public function boot()
{
echo "curl provider boot<br>";
}
在 config/app.php 中註冊服務提供者
直接在 providers 引數中新增 App\Providers\CurlServiceProvider::class,
驗證
任意註冊一個空的路由,透過頁面訪問,可以看到剛才在 register 和 boot 中寫的輸出語句列印出來,說明我們的服務提供者已經被註冊和啟動了,在 http 控制器中,透過 \App::make('curl') 便可以訪問到我們新新增的服務提供者,進行 get|post 傳送請求。
延遲服務提供者
如果系統在啟動時載入的提供者過多,必然會導致系統效能下降,好在 laravel 框架為我們提供延遲載入服務提供者的功能,只有真正使用到改服務提供者時,才進行繫結和啟動。
延遲服務提供者需要修改的地方
class CurlServiceProvider extends ServiceProvider
{
protected $defer = true;
/**
* 中間不變的地方暫時省略
*
*/
public function provides()
{
return ['curl'];
}
}
利用框架的 artisan 命令生成快取檔案
執行 php artisan clear-compiled ,會重新生成框架快取檔案,在 bootstrap/cache/services.php 中儲存系統服務提供者的所有資訊,其中 deferred 儲存的是所有需要延遲載入的服務提供者。
延遲載入註冊啟動邏輯
/**
* vendor/laravel/framework/src/Illuminate/Foundation/Application.php
* Resolve the given type from the container.
*
* (Overriding Container::make)
*
* @param string $abstract
* @param array $parameters
* @return mixed
*/
public function make($abstract, array $parameters = [])
{
$abstract = $this->getAlias($abstract);
if (isset($this->deferredServices[$abstract]) && ! isset($this->instances[$abstract])) {
$this->loadDeferredProvider($abstract);
}
return parent::make($abstract, $parameters);
}
上邊程式碼是系統服務容器解析實現類的邏輯,中間有一層判斷,如果待解析的類在延遲載入服務提供者列表中,並且是首次解析時,便會呼叫延遲載入函式 loadDeferredProvider , 呼叫服務提供者的 register 和 boot 函式進行註冊和繫結。之後在進行後續解析。
透過對 laravel 框架服務提供者邏輯的理解,手動建立一個傳送請求的 CurlServiceProvider 服務提供者,並且實現延遲載入,降低對框架系統效能的影響。如有不對,還請指教
本作品採用《CC 協議》,轉載必須註明作者和本文連結