IoC容器是控制反转的实现机制,通过$bindings、$instances和反射协同管理对象创建与依赖注入,支持bind/singleton/make操作,并推荐构造函数注入而非服务定位器。

IoC 容器不是“容器”,而是一种控制权的移交
在 Laravel 6 中,服务容器本质上是 IoC(Inversion of Control,控制反转)容器。它不单是存对象的“盒子”,而是把「谁来创建对象、何时创建、依赖怎么来」这些控制权,从开发者手里交出去——交给框架统一管理。比如以前写 $db = new Database();,现在变成声明「我需要一个 Database」,由容器自动给你准备好,连它的依赖(比如连接配置、日志驱动)也一并解决。
底层靠两个核心结构 + 反射 + 闭包协同工作
容器实现并不神秘,关键在三块:
-
$bindings 数组:记录「什么抽象名 → 对应怎么造出实例」。例如
bind('cache', function () { return new FileCache(); }),就把cache这个标识和构造逻辑存进去了; -
$instances 数组:只存已创建的单例对象,如
singleton('db', ...)第一次调用make('db')后,实例就落进这里,下次直接返回,不再执行回调; -
PHP 反射(Reflection):当没显式绑定某个类(比如
make(UserRepository::class)),容器会用ReflectionClass检查它的构造函数,看参数类型提示(如__construct(Connection $conn)),再递归去make($conn)——这个过程全自动,无需手动传参。
bind / singleton / make 是最常打交道的三个动作
它们构成了使用容器的主干链路:
-
bind('logger', fn() => new Logger()):每次make('logger')都新建一个实例; -
singleton('cache', fn() => new RedisCache()):首次调用才执行回调,之后始终复用同一个对象; -
make('logger')或app('logger'):触发整个解析流程——查$instances→ 查$bindings→ 反射构造 → 返回实例。
别混淆服务定位器,它只是容器的“快捷查找方式”
像 app('cache') 看似方便,但它属于 服务定位器模式,本质是让类主动去容器里“找”依赖。这会隐藏真实依赖,不利于测试。Laravel 推荐的是 构造函数注入:public function __construct(Cache $cache) { ... }——依赖明明白白写在签名里,容器在实例化时自动塞进去,解耦更彻底,也更符合依赖倒置原则。


















