关闭

[置顶] laravel 框架 三种绑定 bind、singleton、instance 源码分析

标签: laravel
621人阅读 评论(0) 收藏 举报
分类:

laravel 框架采用IoC模式即(inversion  of  Controller)控制反转进行类的操作。将要使用的类提前绑定到容器中。今天我们讲解的不是IoC,主要通过laravel 源码分析三种绑定的区别,有利于大家对laravel框架有更进一步的了解。

一、instance 绑定

      首先我们来看一下instance方法的代码

public function instance($abstract, $instance)
{

    //移除已经存在的抽象的别名
    $this->removeAbstractAlias($abstract);
   //检查是否已经存在该别名的绑定的对象
    $isBound=$this->bound($abstract);
    unset($this->aliases[$abstract]);

    // We'll check to determine if this type has been bound before, and if it has
    // we will fire the rebound callbacks registered with the container and it
    // can be updated with consuming classes that have gotten resolved here.
    $this->instances[$abstract] = $instance;

    // 判断是否已经绑定
    if ($isBound) {
        $this->rebound($abstract);
    }
}
可以看到在instance方法中,首先移除已经存在的相同的别名,然后将对象存入$this->instance 数组中。然后完成了绑定。

二、bind 绑定

同样的,我们先贴出代码

public function bind($abstract, $concrete = null, $shared = false)
{
    // If no concrete type was given, we will simply set the concrete type to the
    // abstract type. After that, the concrete type to be registered as shared
    // without being forced to state their classes in both of the parameters.

    //移除旧的实例
    $this->dropStaleInstances($abstract);
    if (is_null($concrete)) {
        $concrete = $abstract;
    }
    // If the factory is not a Closure, it means it is just a class name which is
    // bound into this container to the abstract type and we will just wrap it
    // up inside its own Closure to give us more convenience when extending.
    if (! $concrete instanceof Closure) {
        $concrete = $this->getClosure($abstract, $concrete);
    }
    // 创建一个包含变量与其值的数组。
    //对每个参数,compact() 在当前的符号表中查找该变量名并将它添加到输出的数组中,变量名成为键名而变量的内容成为该键的值。简单说,它做的事和 extract() 正好相反。返回将所有变量添加进去后的数组。
    $this->bindings[$abstract] = compact('concrete', 'shared');

    // If the abstract type was already resolved in this container we'll fire the
    // rebound listener so that any objects which have already gotten resolved
    // can have their copy of the object updated via the listener callbacks.
    //检查是否解析过 或则 已经存在所要绑定对象对应的实例
    if ($this->resolved($abstract)) {
        $this->rebound($abstract);
    }
}
使用bind 的形式如下:

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

在bind 方法中 首先移除旧的实例,绑定的对象实例一般是放在闭包中,如果第二个参数不是闭包,是类名,会通过getClosure函数将类名封装进闭包中,然后在闭包中通过容器的make或build函数解析该类。绑定会将相应的闭包以及是否share 放进$this->bindings数组中。在解析的时候调用。

singleton 绑定

/**
 * Register a shared binding in the container.
 *  绑定到容器的对象只会被解析一次,之后的调用都返回相同的实例:
 * @param  string|array  $abstract
 * @param  \Closure|string|null  $concrete
 * @return void
 */
public function singleton($abstract, $concrete = null)
{
    $this->bind($abstract, $concrete, true);
}
可以知道singleton 只是bind的一个调用。

这就是对laravel框架中三个绑定的源码分析。

如果您觉得我的文章有用,请随意打赏。


1
0
查看评论

Laravel的核心概念

工欲善其事,必先利其器。在开发Xblog的过程中,稍微领悟了一点Laravel的思想。确实如此,这篇文章读完你可能并不能从无到有写出一个博客,但知道Laravel的核心概念之后,当你再次写起Laravel时,会变得一目了然胸有成竹。PHP的生命周期万物皆有他的生命周期。熟悉Android的同学一定熟...
  • u013474436
  • u013474436
  • 2016-10-18 11:27
  • 5991

laravel的依赖注入

首先创建service层的接口类,和实现类。在app文件夹下面创建services文件夹。 (1)接口类: <?php namespace App\Services; use App\models\Users; interface IUserService{ /** ...
  • gaoxuaiguoyi
  • gaoxuaiguoyi
  • 2015-11-25 21:35
  • 980

Mybatis异常There is no getter for property named或Returning cached instance of singleton bean

mapper接口中的参数需要加上@Param(value="xxx"),如:getComFairList(@Param(value = "comCode") String comCode)
  • u011712163
  • u011712163
  • 2017-02-28 16:53
  • 4306

Spring Bean 单例模式

1. Refer to >, page 39. 2. Spring Bean Creation is Not Thread Safe refer to http://blog.imaginea.com/spring-bean-creation-i...
  • nomad2
  • nomad2
  • 2015-12-09 09:45
  • 2977

Spring3.1.1浅析(一)

首先了解一下spring的启动细节: 1、  创建maven工程,pom文件中加入对spring的依赖和log4j的支持: 2、建立两个测试类,其中service中包含对dao的引用,然后定义一个Test类进行测试用: package com.yushh.test.chap...
  • Cages
  • Cages
  • 2012-03-27 21:15
  • 4729

laravel中间件源码分析

转载自:http://www.cnblogs.com/z1298703836/p/5241541.html laravel中间件源码分析 在laravel5.2中,HTTP 中间件为过滤访问你的应用的 HTTP 请求提供了一个方便的机制。在处理逻辑之前,会通过中间件...
  • xiao_tommy
  • xiao_tommy
  • 2016-11-24 08:19
  • 455

设计模式--单例模式(Singleton)

单例对象(Singleton)是一种常用的设计模式。在Java应用中,单例对象能保证在一个JVM中,该对象只有一个实例存在。这样的模式有几个好处: 1、某些类创建比较频繁,对于一些大型的对象,这是一笔很大的系统开销。 2、省去了new操作符,降低了系统内存的使用频率,减轻GC压力。 ...
  • zczzsq
  • zczzsq
  • 2013-08-23 14:31
  • 3035

Laravel源码解析一 【请求的生命周期】

不BB,直接开始。 看一个框架的源码,第一步我们先看入口文件。 laravel的入口文件在public目录下的index.phprequire __DIR__.'/../bootstrap/autoload.php';这玩意是加载composer的一些东西,自动加载有需要的类。具...
  • u013705066
  • u013705066
  • 2017-01-04 15:51
  • 1947

mangos0.9代码分析(一)

最近下到了一份mangos0.9版本的源码,打算用心读一读,也算是学习学习。 当然这也是本人第一次接触游戏服务器源码,估计会遇到很多很多的问题,这篇文章也是本人的第一篇博客,来csdn那么多年了,终于打算开始写点东西了,接下来的一段时间,想自己研究研究这份代码,随手写点东西也算是做了笔记了。 &...
  • xiaoguaiyin
  • xiaoguaiyin
  • 2012-09-18 22:09
  • 1538

关于Singleton,static,new对象的深入思考

new的过程假如有一个Cat类,这个类没有继承关系Cat cat = new Cat();1)所有的类都是在第一次使用时,动态的加载到JVM中。当首次创建一个Cat类,或者 访问Cat类的静态,或者访问Cat的静态变量时,java解释器就会查找classPath,定位 到Cat.class文件 ...
  • u014245719
  • u014245719
  • 2015-04-04 16:07
  • 1064
    个人资料
    • 访问:42544次
    • 积分:1195
    • 等级:
    • 排名:千里之外
    • 原创:74篇
    • 转载:33篇
    • 译文:1篇
    • 评论:22条
    文章分类
    最新评论