Facade是容器中的類的靜態(tài)代理,可以調(diào)用容器中任何對象的任何方法钠导。
Route::get(‘/cache’, function(){
????????return Cache::get(‘key’);
});
要使用Facade,首先需要繼承‘Illuminate\Support\Facades\Facade’類并且實(shí)現(xiàn)一個抽象方法‘getFacadeAccessor’。
use Illuminate\Support\Facades\Facade;
class Cache extends
Facade
{
? ? /**
????*獲取組件注冊名稱
? ? *
? ? * @return string
? ? */
? ? protected static function getFacadeAccessor() {
? ? ? ? return 'cache';
? ? }
}
‘getFacadeAccessor’ 這個方法只要返回一個容器綁定類的名字即可森瘪,當(dāng)然也可以直接返回一個類如:
use
Illuminate\Support\Facades\Facade;
use Cache;
class Cache extends
Facade
{
? ? /**
????*獲取組件注冊名稱
? ? *
? ? * @return string
? ? */
? ? protected static function getFacadeAccessor() {
? ? ? ? return new Cache;
? ? }
}
Facade的核心是使用了‘__callStatic’這個魔術(shù)方法牡属,使用了這個方法之后,即可直接調(diào)用Cache中的get方法扼睬,盡管這個方法在Cache類中并不存在逮栅。
public static
function __callStatic($method, $args)
{ $instance =static::getFacadeRoot();? ? //解析出實(shí)例
? ? ? ? if (! $instance) {
? ? ? ? ? ? throw new RuntimeException('A facade root has not been set.');
? ? ? ? }
????????return$instance->$method(...$args);? ? //調(diào)用方法
}
然后以下的在Facade中的方法可以從容器中解析出對象:
public static function getFacadeRoot(){
? ? return static::resolveFacadeInstance(static::getFacadeAccessor());
}
protected static function getFacadeAccessor(){
? ? throw new RuntimeException('Facade does not implement getFacadeAccessor
????method.');
}
protected static function resolveFacadeInstance($name){
? ? if (is_object($name)) {
? ? ? ? return $name;
? ? }
? ? if (isset(static::$resolvedInstance[$name])) {?
? ? ? ? return static::$resolvedInstance[$name];
? ? }
? ? return static::$resolvedInstance[$name] = static::$app[$name];
}
其中的'getFacadeAccessor'這個方法必須被重寫,否者就會拋出異常。然后在'resolveFacadeInstance'這個方法中會先判斷是否是一個對象措伐,如果是的話就直接返回特纤。所以上文說的'getFacadeAccessor'這個方法直接返回一個對象也是可以的,奧秘就在這侥加。
然后會去判斷需要解析的對象是否已經(jīng)解析過了叫潦,如果解析過了就直接返回,否則會從容器中去解析再返回官硝,這樣不僅僅實(shí)現(xiàn)了單例矗蕊,而且還可以提升性能。
得到對象后氢架,就是直接通過對象來調(diào)用方法了傻咖。