IOC 容器
入口文件 index.php
1 | 1、加载框架依赖 |
app.php 文件(require_once DIR.’/../bootstrap/app.php’)
1 | 1、创建容器 |
app 容器
打印 app 容器
1 | 1、serviceProviders 属性 |
注册服务提供者
注册服务提供者只需要继承 ServiceProvider 抽象类即可(放在那儿都可以),并在 config/app.php providers 数组
里面注册或使用 app()->register(TestProvider::class)(此方法 $defer 属性无效) 即可
1 | 1、继承 ServiceProvider 抽象类 |
注册服务提供者别名
app()->alias(‘testProvider’,’test’) 别名数量无限制
app 容器绑定
1、app()->bind($abstract, $concrete = null, $shared = false)
第一个参数是服务绑定名称,第二个参数是绑定结果(参数类型:\Closure|string|null),第三个参数是否共享(类似
单例),默认为 false,第二个参数,如果是非闭包,内部会包裹上闭包,好处是延迟加载,节约空间
2、app()->singleton($abstract, $concrete = null)
第一个参数是服务绑定名称,第一个参数是绑定结果,在内部是调用了 app()->bind($abstract, $concrete = null, true),
第三个参数为 true
3、app()[‘test’] = function(){ return ‘test’ }
使用了 PHP ArrayAccess 接口,在内容调用了 app()->bind() 方法,第三个参数为 false
4、app()->instance(‘test’,实例)
绑定一个实例,跟上面三个比,就是少了一个闭包
app 容器解析
1 | 1、app($abstract, $parameters = []) |
DI 依赖注入
DI 是 IOC 的一种实现,DI 是一种设计模式,IOC 是一种设计思想,DI 实现原理是使用 PHP 反射机制来反射出相应依赖对
象名称,通过 aliases 属性得到服务名称,然后从容器解析出服务实例,最后传入对应方法,这个过程就是所谓的依赖注入
总结
Laravel 是一个组件式框架,实现了高度解耦,再使用 IOC 容器来管理解耦后的组件,我把这个容器理解为使用了对象的高级注册树,当组件越来越多时,那么这个容器对象不是越来越大吗?所以 Laravel 使用了闭包来延迟加载,但是有个问题,如果每次获取都去 new 一次,不是很浪费时间与空间吗?在能满足需求的情况下,能不能只 new 一次(类似单例),所以 Laravel 又引入了 shared 来实现单例,用 instances 属性来保存单例(服务在生命周期内,shared 不可更改,而且 Laravel 大部分服务 shared 都为 true),现在又有个需求,当某个动作发生时,就触发服务加载?所以 Laravel 又加入了 when 方法来绑定事件,前提是这个服务 shared 必须为 true。