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 写入');