use Illuminate\Support\Facades\Cache;
use Illuminate\Support\Facades\Log;
use Illuminate\Support\Facades\Route;
Cache::add('user','bbb',100);
$vv=app();
dd(Cache::getFacadeApplication() instanceof $vv);
lumen门面模式实现原理:
在项目启动时,lumen启动了 Laravel\Lumen\Application 容器,调用了 withAliases() 这个方法,将系统使用的容器把门面类加载进来。
我们在项目中,use Illuminate\Support\Facades\Log;
就可以使用 Log::info('使用门面模式写一个日志'); 就可以使用这样的方法写日志了。
那么打开 Illuminate\Support\Facades\Log 这个文件,也看不到 info 这个方法啊,这到底怎么回事?
下面听我一一道来:
门面模式 简单来说就是类的静态方法调用(个人理解、大神勿喷)
要理解门面模式离不开:Illuminate\Support\Facades\Facade; 这个类,这是门面模式的核心。
lumne实现门面模式用到了两个技术点 __callStatic($method, $args) 静态方法找不到 调用这个方法 还有一点是 ...$args 变长参数 、class_alias() 这个函数
bootstarp/app.php 启动框架
|
|
|
系统启动,会实例化
Laravel\Lumen\Application 这个对象
|
|
|
会加载 门面类
use Illuminate\Support\Facades\Facade;
|
|
|
$app->withFacades(); 加载门面类
方法如下:
/** * Register the facades for the application. * * @param bool $aliases * @param array $userAliases * @return void */ public function withFacades($aliases = true, $userAliases = []) { Facade::setFacadeApplication($this); if ($aliases) { $this->withAliases($userAliases); } } 方法中调用了下面这个方法: /** * Register the aliases for the application. * * @param array $userAliases * @return void */ public function withAliases($userAliases = []) { $defaults = [ 'Illuminate\Support\Facades\Auth' => 'Auth', 'Illuminate\Support\Facades\Cache' => 'Cache', 'Illuminate\Support\Facades\DB' => 'DB', 'Illuminate\Support\Facades\Event' => 'Event', 'Illuminate\Support\Facades\Gate' => 'Gate', 'Illuminate\Support\Facades\Log' => 'Log', 'Illuminate\Support\Facades\Queue' => 'Queue', 'Illuminate\Support\Facades\Route' => 'Route', 'Illuminate\Support\Facades\Schema' => 'Schema', 'Illuminate\Support\Facades\URL' => 'URL', 'Illuminate\Support\Facades\Validator' => 'Validator', ]; if (! static::$aliasesRegistered) { static::$aliasesRegistered = true; $merged = array_merge($defaults, $userAliases); foreach ($merged as $original => $alias) { class_alias($original, $alias); } } }
把门面类注册到系统中....
再看看门面类:
Illuminate\Support\Facades\Facade.php
//其实 和 app() 获取到的对象是一个 instanceof true
public static function getFacadeApplication(){
return static::$app;
}
//设置app容器进来,在哪里注册进来的呢? 向上看 withFacades 这个方法中 有这么一句: Facade::setFacadeApplication($this);
public static function setFacadeApplication($app){
static::$app = $app;
}
/** * Handle dynamic, static calls to the object. * * @param string $method * @param array $args * @return mixed * * @throws \RuntimeException */ public static function __callStatic($method, $args) { //去app容器中拿已经注册的服务 $instance = static::getFacadeRoot(); if (! $instance) { throw new RuntimeException('A facade root has not been set.'); } //动态去调用方法,把结果返回 return $instance->$method(...$args); }
这就是门面模式的运行原理。
再简单概述一下:(需要搞清楚一点,门面模式是使用静态方法去调用动态类的方法 把结果返回)
Log::info('门面模式log 写入');