• laravel5.5容器


    容器主要是为了实现控制反转,控制反转的最终目的是减少类的耦合

    1. 比较典型的例子就是 cache 缓存

    # 不反转的例子 Cache类依赖Redis, 每次使用缓存的时候我们都要new Redis()
    class Cache {
        public function __construct()
        {
            $this->store = new Redis();
        }
    }
    
    # 反转使用容器, 由容器实例化对应的类,把控制权给了容器, 每个使用缓存的地方, 引入的都是容器, 使用make解析出 缓存对象
    class Cache {
        public function __construct(Container $container)
        {
            $this->$container = $container;
    
            $this->store = $this->container->make('cache');
        }
    }
    

    容器如何解析出redis缓存呢

    # 类似这样,绑定一个redis对象,使用的时候直接make()解析即可
    $this->app->singleton('cache', function ($app) {
        return new Redis($app);
    });
    

    试想: 如果我们有一天不想用redis缓存了,不使用反转的时候,我们是不是不需要去每个使用缓存的类中修改,使用反转的话是不是只需要在绑定的时候修改即可,当然实际的应用中,我们也不必去修改绑定,我们可以类似的通过配置来实现快速切换。

    # CacheManager类中你可以通过读取配置getConfig()等等来控制你想要的逻辑
    $this->app->singleton('cache', function ($app) {
        return new CacheManager($app);
    });
    

    2. 容器顾名思义,其实就是完成存取过程

    • 先往容器里绑定东西---绑定过程
    • 再向容器拿绑定过的东西---解析过程

    2.1 绑定过程

    我们都可以绑定什么呢,官方给出了4种绑定

    简单绑定

    传递我们想要注册的类或接口名称再返回类的实例的 Closure :

    $this->app->bind('HelpSpotAPI', function ($app) {
        return new HelpSpotAPI($app->make('HttpClient'));
    });
    

    绑定单例

    singleton 方法将类或接口绑定到只能解析一次的容器中。绑定的单例被解析后,相同的对象实例会在随后的调用中返回到容器中:

    $this->app->singleton('HelpSpotAPI', function ($app) {
        return new HelpSpotAPI($app->make('HttpClient'));
    });
    

    绑定实例

    你也可以使用 instance 方法将现有对象实例绑定到容器中。给定的实例会始终在随后的调用中返回到容器中

    $api = new HelpSpotAPI(new HttpClient);
    
    $this->app->instance('HelpSpotAPI', $api);
    

    绑定初始数据

    当你有一个类不仅需要接受一个注入类,还需要注入一个基本值(比如整数)。你可以使用上下文绑定来轻松注入你的类需要的任何值:

    $this->app->when('AppHttpControllersUserController')
              ->needs('$variableName')
              ->give($value);
    

    2.2 解析过程

    laravel使用resolve方法来进行解析, 核心的思路:

    1. 首先判断instances中是否有abstract, 有的话,直接返回。没有接着往下看。

    2. 其次,判断bindings里面有没有abstract,有的话拿到注册的匿名函数, 并执行匿名函数。

    3. 前两步都没有找到的话,那laravel会把abstract当作一个类名,然后通过反射 构建这个类名的实例化对象。所以不需要事先绑定一个类, 通过Make函数可以直接实例化类 当然需要可自动加载这个类。试想我们是不是可以通过App::make()方法来实例化一个类。

    laravel提供了make方法实现resolve过程

        # 注意 make 是不能传递参数的
        
        public function make($abstract)
        {
            return $this->resolve($abstract);
        }
    

    如果每次都去make是不是很麻烦,于是laravel实现了arrayAccess的机制。

    比如上面例子绑定的cache,我们可以这样取

    $store = $this->app['cache']
    
    app('cache')
    

    更进一步,laravel还有aliases

    通过config/app.php中的aliases数组,找到facades类,继而找到容器中的绑定项

        'aliases' => [
            'Cache' => IlluminateSupportFacadesCache::class,
            // ...其他配置
        ],
    ```
    
    实际上还有一种通过自动注入
    
    你可以简单地使用「类型提示」的方式在由容器解析的类的构造函数中添加依赖项,包括 控制器、事件监听器、队列任务、中间件 等。 事实上,这是你的大多数对象也应该由容器解析。
    
    ```
    <?php
    
    namespace AppOrders;
    
    use IlluminateContractsCacheRepository as Cache;
    
    class Repository
    {
        protected $cache;
    
        public function __construct(Cache $cache)
        {
            $this->cache = $cache;
        }
    }
    ```
  • 相关阅读:
    自学大数据初期
    研究正则表达式
    智能穿戴设备移动APP端与外设数据传输协议
    集成Facebook SDK
    Core Data数据库迁移
    用Time Machine做更换电脑工具
    iOS Automation Test
    编译libcore-amr静态库
    解决CentOS 7安装zabbix 3.0 无法启动zabbix-server的问题[segfault at 18 ip 00007f78842b4bd0 sp 00007fff1995a818 error 4 in libpthread-2.17.so[7f78842ab000+16000]]
    CentOS 7 安装Percona,Xtrabackup
  • 原文地址:https://www.cnblogs.com/redirect/p/8658685.html
Copyright © 2020-2023  润新知