服務容器、依賴注入、門臉模式
-
服務容器
容器概念
用來裝一個個實例的對象,比如郵件類。
IOC控制反轉
IOC(Inversion of Control)控制反轉,面向對象,可降低代碼之間的耦合度,借助第三方實現具有依賴關系的集合。
laravel 容器位置:bootstrap/app.php 中
$app = new Illuminate\Foundation\Application( realpath(__DIR__.'/../') ); //可通過 public/index.php $app = require_once __DIR__.'/../bootstrap/app.php'; 獲取該路徑
綁定 $this->app->bind('HelpSpot\API',function($app){return new HelpSpot\API\($app->make('HttpClient'))}); $this->app->singleton('HelpSpot\API',function($app){return new HelpSpot\API\($app->make('HttpClient'))}); 解析 $this->app->make('HelpSpot\API');
DI依賴注入
DI依賴注入是一種設計思想,將實例遍歷到對象中,laravel通過反射來完成。eg:
public function edit(Post $post){ return view("post/edit",compact('post')); }
-
服務提供者
服務提供注冊方法:
- register() //所有提供者提供服務之前提供
- boot() //所有提供者提供服務之后提供
延遲服務提供配置:
protected $defer = true;
服務提供位置:
- 配置文件:config/app.php providers=>[...]
- 框架中固定寫好的:eg:注冊服務 registerBaseServiceProviders() //position: vendor/laravel/framework/src/Illuminate/Foundation/Application.php
-
門臉模式
為容器中可用的類提供一種靜態的調用方法 eg:\Request::all()
位置:config/app.php
eg:
aliases=>[ 'Request' => Illuminate\Support\Facades\Request::class, ... ]
其實,所有的門臉類中只有一個方法,即返回對應的IOC控制反轉中的標簽
namespace Illuminate\Support\Facades; /** * @see \Illuminate\Http\Request */ class Request extends Facade { /** * Get the registered name of the component. * * @return string */ protected static function getFacadeAccessor() { return 'request'; } }
-
示例分析日志類
查看日志:
tail -f storage/logs/laravel.log
-
1.容器
vendor/laravel/framework/src/Illuminate/Foundation/Application.php 中找到 registerBaseServiceProviders()方法,追蹤到下面方法register(),可看出綁定到 log 字符串
public function register()
{
$this->app->singleton('log', function () {
return $this->createLogger();
});
}
code:
$app = app(); //獲取容器 $log = $app->make('log'); //從容器中獲取日志類,並解析(找到綁定的過程確定容器中字符串)
$log->info("post_index",['data'=>'hello log!']);
-
2.依賴注入
服務注冊名字叫log可在當前文件找出設置的別名,其對應的三個別名都相當於獲取log,position:vendor/laravel/framework/src/Illuminate/Foundation/Application.php,
'log' => [\Illuminate\Log\Writer::class, \Illuminate\Contracts\Logging\Log::class, \Psr\Log\LoggerInterface::class],
code:
public function index(\Illuminate\Log\Writer $log){ $log->info('post_index',['data'=>'hello log!']); }
-
3.門臉模式:
通過 config/app.php 設置 aliases
'Request' => Illuminate\Support\Facades\Request::class,
code:
public function index(){ \Log::info('post_info',['data'=>'hello menlian!']); }