前言
通过实现laravel 框架功能,以便深入理解laravel框架的先进思想。
什么是服务容器
服务容器是用来管理类依赖与运行依赖注入的工具。Laravel框架中就是使用服务容器来实现 控制反转和依赖注入。
什么是控制反转(IoC)和依赖注入(DI)
控制反转(IoC) 就是说把创建对象的控制权进行转移,以前创建对象的主动权和创建时机是由自己把控的,而现在这种权力转移到第三方,也就是 Laravel 中的容器。
依赖注入(DI)则是帮助容器实现在运行中动态的为对象提供提依赖的资源。
概念容易不太容易让人理解,举个栗子:
1 | //我们构建一个人的类和一个狗的类 |
这个人在遛狗,突然遇到了死对头,他于是放狗咬人
1 | $people = new People(); |
在这个操作中,people类要执行putDog()
这个方法,需要依赖Dog类,一般我们像上面一样,在people中利用构造函数来添加这个Dog依赖。如果使用控制反转 依赖注入则是这个样子
1 | class People |
People类通过构造参数声明自己需要的 依赖类,由容器自动注入。这样就实现了程序的有效解耦,好处在这就不多说了。
Laravel容器依赖注入的实现
实现原理需要了解的知识点:
闭包(匿名函数):
匿名函数(Anonymous functions),也叫闭包函数(closures),允许 临时创建一个没有指定名称的函数反射:PHP 5 以上版本具有完整的反射 API,添加了对类、接口、函数、方法和扩展进行反向工程的能力。 此外,反射 API 提供了方法来取出函数、类和方法中的文档注释
理解了闭包和反射的基本用法我们来看Laravel中是怎么实现容器的,下面代码是我对laravel框架容器部分代码的简化核心版:
1 | class Containerc |
容器的工作流程
接着上面遛狗的例子:
1 | //实例化容器类 |
上面示例中我们先实例化容器类,然后使用bind()
方法 绑定接口和 生成相应的实例的闭包函数。然后使用make()
函数生成实例对象,在make()
中会调用 isBuildable($concrete, $abstract)
来判断 给定的服务实体($concrete
参数)是否可以创建,可以创建 就会调用 build($concrete)
函数 ,build($concrete)
函数会判断传的参数是 是 闭包 还是 具体类名 ,如果是闭包则直接运行,如果是具体类名的话,则通过反射获取该类的构造函数所需的依赖,完成实例化。
重点理解 下面这几个函数中 反射的用法,应该就很好理解了
1 | build($concrete) |
最后
IoC 理解起来是有点难度,可能文中描述让你感觉不是很清楚,可以将文中代码 在php中用debug观察 运行状态。
理解了容器的具体实现原理,再去看Laravel中的相关实现,就会感觉豁然开朗。