Laravel5学习四:Facade的运行机制

原创
2016-06-23 13:32:12634浏览

什么是Facades

官方文档如是说:

Facades 提供一个 静态接口 给在应用程序的 服务容器 中可以取用的类。Laravel 附带许多 facades,甚至你可能已经在不知情的状况下使用过它们!Laravel 的「facades」作为在 IoC 容器里面的基础类的静态代理,提供的语法有简洁、易表达的优点,同时维持比传统的静态方法更高的可测试性和弹性。

说实话,这段话读起来真不像人类的语言,我准备来拆解一下。
首先, Facades 是一个类,是一个什么类呢?它是基础类的一个静态代理。
其次, Facades 是可以直接从IOC容器中拿到的,对应到laravel5就是说,可以直接使用,它已经存在于app这个容器中。
最后, 为什么要有 Facades 这个东东?首先优点是:它提供的语法更简洁,易表达。这个其实不是主要原因,个人觉得最主要的原因是:便于可测试性与降低耦合性(代理模式的优点)

用例子来说明

PS:本部分内容参考自网络:原文地址

我们知道$app 在laravel中是一个特殊的全局变量,它在最初启动的时候就是ioc容器的对象实例。
于是如果我们要取从ioc容器中取一个实例出来,是这样写的:

$value = $app->make('cache')->get('key');

由于$app implements PHP的 ArrayAccess interface,所以可以更简化点,写成:

$value = $app['cache']->get('key');

你甚至可以用函数的方式写成这样:

$value = app('cache')->get('key');

这个时候Facace跳出来说,我可以写成这样:

$value = Cache::get('key');
运行机制分析
  • Facades 的命名空间
    相信只要玩过laravel的人,都会见过当遇到 Facades 的时候,导入命名空间,只需要用 use XXX 即可。不用把完整的的命名空间写出来。这是为什么?
    正常的类的命名空间,应该这样写:
  • use Illuminate\Support\Facades\Cache;

    Facades 只需要这样写:

    use Cache;

    为什么能够这样?我看了一些它的运行过程,解析如下:

    这幅图,中的关键点是:AliasLoader中注册的自动加载方法,它使用了我们在app.php配置中的 aliases 数组,从而通过这个别名,可以找到对应的真实类存在的文件,然后完成对象的实例化。

  • 如何构建自己的 Facades
    PS:还是以 Cache 为例子
  • 首先需要构建的就是Cache这个类本身,实现它的功能。这里对应的文件是:
    Illuminate\Cache\CacheManager (备注:由于Cache有多种实现,因此通过管理者来获取想要的Cache实现方案。)

    当Cache这个类,写好之后,我们要将它绑定到一个服务提供者里边去,这里的服务提供者位置是:
    Illuminate\Cache\CacheServiceProvider ,绑定部分代码是:

    public function register() {    $this->app->singleton('cache', function ($app) {        return new CacheManager($app);    });    ......    }

    这里需要注意的是,绑定时,为什么要使用’cache’ 这个字符串,后面会讲到。当服务提供者写好后,需要在 app.php 的 providers 的数组中配置服务提供者,此处代码如下:

    'providers' => [    /* * Laravel Framework Service Providers... */    Illuminate\Foundation\Providers\ArtisanServiceProvider::class, Illuminate\Auth\AuthServiceProvider::class, Illuminate\Broadcasting\BroadcastServiceProvider::class, Illuminate\Bus\BusServiceProvider::class, Illuminate\Cache\CacheServiceProvider::class, ...... ]

    完成以下步骤后,就可以构建 Facades 类了,Cache 的 Facades 的位置在 Illuminate\Support\Facades\Cache 。

       

    所有的 Facades 类都需要继承自 Facades ,并实现 getFacadeAccessor 方法。它的工作是定义要从容器解析什么。这也就是说,如果我们绑定的时候,写的是 cache ,那么这里也需要返回 cache ,要不然解析的时候,就会找不到。大家可以试试改成其它名字。
    最后一步,需要配置 app.php 中的 aliases 数组,这涉及到 Facades 的自动加载。就是最开始画的那幅图。

    'aliases' => [    'App'       => Illuminate\Support\Facades\App::class, 'Artisan' => Illuminate\Support\Facades\Artisan::class, 'Auth' => Illuminate\Support\Facades\Auth::class, 'Blade' => Illuminate\Support\Facades\Blade::class, 'Bus' => Illuminate\Support\Facades\Bus::class, 'Cache' => Illuminate\Support\Facades\Cache::class, ...... ]

    声明:本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn核实处理。