Laravel 执行流程(五)之 认识 Make
备注:纯手打的学习笔记,如有错误之处请指正,谢谢。希望大家学的开心!
上一章了解了 bind
,bind
封装了一个闭包到数组 bindings
,那绑定完了总需要使用吧,就好像生产零件,先规定了怎么生产( bind
),然后再生产( make
)所以 make
出来了,咱们一起看看,make
在容器里面起到什么作用。
还是老办法,先找出第一次调用 make
的地方,之前第三章探索 application
构造函数还是很有必要的,因为若干的第一次 work,以及认识这些关键的方法都包含在内,如果对以下所说的方法比较模糊,自行回顾第三章,并打开代码走一遍。
我们知道 application
构造函数里面调用了 registerBaseServiceProviders
(注册基本的服务提供商),内部调用了 register
方法,register
方法内部又调用了 markAsRegistered
(标记为已注册),咱们现在看 markAsRegistered
方法:
后2行代码很简单,但至于有什么用,不是本章的主题,我们主要看第一行代码。
忘记第二章说过的 The ArrayAccess interface
数据访问接口的同学,看到这里可能就懵B了,我们说过当这种形式 $this[‘xx’]
出现的时候,调用的是 container
类中的 offsetGet
方法:
也就是说是返回 make
后某个东东,才执行的 fire
方法;而我们主要说的是 make
,不是 fire
。
现在 $key
的参数是 events
,这个不用解释了哈;咱们先看看方法注释和参数原型截图:
正式执行 make
:
先是获取正确的别名 getAlias
。
接下来也是一个单例的判断,如果当前 instances
数组包含此类型,则直接 reutrn
此单元。
接着执行了一个新玩意 getConcrete
并将结果赋值给 $concrete
,咱们在跳过去看看 getConcrete
,这个方法的大概意思是得到一个给定的抽象的具体类型。
getConcrete
截图:
先是来了个看不懂的方法 getContextualConcrete
不明觉厉,看截图:
我们暂时还没看到 contextual
数组用过的地方,大家先看看就好。 并且输出 contextual
现在还是空数组,所以回到 getConcrete
方法,判断不成立,继续往下走。
接着,判断我们上一章学过的 bindings
数组,我们知道数组已经包含了 events
这个单元了,什么时候包含的?是在 application
类的 register
方法内执行的 $provider->register()
,而 events
服务商类的 register
方法执行了 $this->app->singleton
,而 singleton
其实在执行 bind
,只不过是共享绑定而已,我们在复习一遍吧。
那也就是说,这里判断不成立,events
已经绑定好了,直接跳过if
块,最后直接
我们知道,这里的 concrete
在 events
单元内是一个闭包对象,在把上一章的截图重发一下
到此为止,getConcrete
理论上已经结束了,但是为了在弄清楚一点,我们继续把刚才if内没有执行的代码说一下:
咱们找到第一次能够执行此场景的代码,在入口文件 index.php
:
首先通过 getAlias
方法,知道现在 $abstract
参数是 app\Http\Kernel
,app\Http\Kernel
到目前为止是没有经过 bind
,所以判断成立,走 if
里面。
第一个判断先是来了个 missingLeadingSlash
方法,意为缺少主斜线,方法内部表达的意思是如果你给的参数是字符串,并且第一个字符不是斜线 \
的话,则返回 true
。
然后 if
第二个判断是,如果 $this->bindings[‘\xxxxx’]
已经绑定的话。
如果2个判断都为 true
,则:
然后直接返回 return $abstract;
所以我们知道,在 getConcrete
方法中,要么返回一个闭包对象,要么返回一个字符串。
接着返回到 make
方法来。
有3个知识点,isBuildable
, build
,还有一个 make
的递归。
isBuildable
,确定给定的具体物是可信赖的。
要么具体物和抽象类型相等,要么具体物就是个闭包方法,至少要满足一样。
好,如果满足其中一样,我们现在场景的 events
是一个闭包,满足了,执行 build
继续看 build
方法:
Build
方法注释大概的意思:为给定的类型实例化一个具体物的实例。
方法开头直接:
终于露出你的庐山真面目了,events
闭包原型,我们在截图确认一下:
嗯哼,$this
参数相当于闭包函数中的参数 $app
,要注意的是 $this
是 application
类,不要认为是在 container
类定义的方法 $this
就是 container
,它们是继承关系,而 new
的是 application
类,所以 $this
属于谁应该很清楚了。
然而就这样执行了闭包,里面的东东肯定是组件的一些功能,这也不是本章主题,所以略过。
至于这个 make
递归,暂时还不知道,等用到的时候在说,目前为止 $object
是一个实例了,我们截图看看是哪个类的实例即可,因为这些都是刚才闭包内执行的结果。
继续往下,没用到的都直接略过。
这个很简单,就是判断 bindings
数组单元内 shared
如果为共享状态(也就是1),则将 $object
进行赋值。
接下来有个 fireResolvingCallbacks
方法,我的理解是启动“具有解析过程”回调函数,目前没有执行到,我们也就不去说了,还是那句话,用的时候在具体来分析,更好理解。
Make
方法最后:
将 true
赋值到 resolved
,意为已经解析过的,最后 return $object
, make
结束。
总结
就像文章标题一样,认识 Make
,我们借助 events
服务进行简单的讲解,还有很多没涉及的地方,以后肯定都会逐一摸透,比如在 build
方法里面的反射具有什么作用等。
那就目前为止,我们知道, make
会借用 bindings(bind而来)
来获取具体的闭包对象,然后用 build
方法来调用闭包函数,所以说 bind
和 make
是具有紧密的联系的,暂时就这么多,欢迎关注下一章。