Laravel 类加载,依赖注入&门面

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/w15249243295/article/details/68962164

Laravel类加载

对于很多新手来说,比如我,刚开始不是很习惯于Laravel这样的类加载。对于第三方拓展,Laravel的加载方式:

  • 为这个类提供一个provider,继承ServiceProvider
  • 重写register方法,singleton或者bind两种方式
  • boot是当前类有依赖其他通过register注册,但是不确定先后顺序的时候使用
  • $defer为true表示延迟加载,默认在Application初始化的时候加载
  • config/app.php配置providers和aliases
  • providers就是执行provider里面定义的register,具体方法是在Application中registerConfiguredProviders,但是aliases是用来做什么的还得再看看。

依赖注入

DI 官方定义是,就是一个类把自己的的控制权交给另外一个对象,类间的依赖由这个对象去解决。

Laravel的依赖注入真的很好用,我刚开始接触Laravel的时候,对于第三方的类,总是习惯于手动初始化。Laravel提供了一种方式,在传参数的时候,通过参数类型+参数名的方式指定。
这种方式的好处是,如果第三方的类有提供provider的方法,比如:

class RedisServiceProvider extends ServiceProvider
{
    /**
     * Indicates if loading of the provider is deferred.
     *
     * @var bool
     */
    protected $defer = true;

    /**
     * Register the service provider.
     *
     * @return void
     */
    public function register()
    {
        $this->app->singleton('redis', function ($app) {
            return new Database($app['config']['database.redis']);
        });
    }

    /**
     * Get the services provided by the provider.
     *
     * @return array
     */
    public function provides()
    {
        return ['redis'];
    }
}

我们在通过Redis $redis这种方式注入的时候,实际拿到的是new Database($app[‘config’][‘database.redis’])。而且因为provider使用的是singleton方式,实现了单例,在这一次请求过程中,我们使用的都是同一个redis实例。
当然通过singleton绑定的还可以用app(‘redis’)这种方式来操作redis。

门面

Laravel的门面使用起来,习惯了IDE的话,如果使用门面来调用方法,在追代码的时候,不能直接跳转到代码的位置就。。
在定义一个门面的时候,都是继承Facade类,实现getFacadeAccessor()方法。

class Log extends Facade
{
    /**
     * Get the registered name of the component.
     *
     * @return string
     */
    protected static function getFacadeAccessor()
    {
        return 'log';
    }
}

abstract class Facade
{
    public static function __callStatic($method, $args)
    {
        $instance = static::getFacadeRoot();

        if (! $instance) {
            throw new RuntimeException('A facade root has not been set.');
        }

        switch (count($args)) {
            case 0:
                return $instance->$method();
            case 1:
                return $instance->$method($args[0]);
            case 2:
                return $instance->$method($args[0], $args[1]);
            case 3:
                return $instance->$method($args[0], $args[1], $args[2]);
            case 4:
                return $instance->$method($args[0], $args[1], $args[2], $args[3]);
            default:
                return call_user_func_array([$instance, $method], $args);
        }
    }
}

我们再使用Log::info这种方式的时候,其实Log这个facade是没有info方法的,它是通过__callStatic,在__callStatic又通过getFacadeRoot拿到app中log的具体实现。
而关于log的使用会在下一篇博客里面提及。

猜你喜欢

转载自blog.csdn.net/w15249243295/article/details/68962164