美文网首页
2021-04-08 laravel 控制反转

2021-04-08 laravel 控制反转

作者: 浩克啊12138 | 来源:发表于2021-04-08 14:42 被阅读0次

    在任意一个实现了ServiceProvider类中的register中添加以下内容。

    $this->app->singleton('dbu', function ($app) {
        return new Dbu($app);
    });
    

    因为其中的$this->app是继承于Container类的,
    那他也是一个容器,通过singleton方法将Dub类绑定在容器中,并设置其名称为 dub

    此时想要引用它就可以通过依赖注入的方式直接引用了
    如:

    public function test(Dbu $dbu)
    {
        dd($dbu->print());
    }
    

    在laravel的Container类中提供了三种不同的注册方法, 分别是bindinstancesingleton, 下面是他们之间的区别



    bindinstancesingleton的区别

    use Illuminate\Container\Container;
    
    class Dbu extends Container
    {
        public function __construct(array $values = [])
        {
            $dbu = $this;
            $this->registerMake($dbu);
        }
    
        public function registerMake($dbu)
        {
     #      ①
            $this->bind('make', function ($dbu) {
                return new AutoLoad($dbu);
            });
     #      ②
    //        $this->singleton('make', function ($dbu) {
    //            return new AutoLoad($dbu);
    //
    //        });
     #      ③
    //        $this->instance('make', function ($dbu) {
    //            return new AutoLoad($dbu);
    //        });
    
            $a = $this['make'];
            $b = $this['make'];
            dd($a, $b, $a == $b, $a === $b);
        }
    }
    

    有一个以上的类, 我们做三次测试:

    • 第一次, 使用bind方法去注册, 返回结果如图1所示

    我们发现$a$b都是AutoLoad的一个实例, 并且是两个完全不同的实例, 每一次的调用实际上就是一次新的实例化

    图1 使用 bind 方法
    • 第二次, 使用singleton方法去注册, 返回结果如图2所示

    这是我们发现$a$b都是AutoLoad的一个实例, 并且两个变量指向的是同一实例, 每一次的调用就是一次对此实例的一个实现

    图2 使用 singleton 方法
    • 第三次, 使用instance方法去注册, 返回结果如图3所示

    这是我们发现$a$b与上两次都不同了, 虽然它们都是指向的同一地址, 但是它们并没有指向真正实例化后的地址, 而是指向了要执行实例化的闭包地址

    图3 使用 instance方法

    看到这里或许已经有一些想法了, 我们试着改一下③的代码,再看一下打印的结果

    # 将之前的闭包去掉直接给他一个实例化的对象
    $this->instance('make',  new AutoLoad($dbu));
    
    图4 修改instance的调用方式

    如图4所示, 这时候就很明显了$a$b指向的都是刚刚newAutoLoad的一个实例对象

    结论:
    bind: 不提前占用内存, 待到调用的时候调用才会进行实例化, 每次都new一个新实例;
    instance: 不提前占用内存, 待到调用的时候, 待到调用的时候调用才会进行实例化, 每次返回的都是同一个实例;
    singleton: 需要提前占用内存, 也就是需要先提前实例化出一个对象, 之后的每次调用都是调用这个实例。

    控制反转具体的介绍或者逻辑可以参考这篇文章

    相关文章

      网友评论

          本文标题:2021-04-08 laravel 控制反转

          本文链接:https://www.haomeiwen.com/subject/ccqvkltx.html