本文目录导读:

不是默认的。
Laravel 的容器(Service Container)在默认情况下,每次通过 app() 或 resolve() 解析一个类时,都会创建一个全新的实例。
它只是默认行为,除非你显式地告诉容器要将某个类绑定为单例(Singleton)。
默认行为:每次都是新实例
如果你只是将类绑定到容器,没有额外设置,每次解析都会产生新对象。
示例:
// 在 ServiceProvider 中
$this->app->bind(LoggerInterface::class, function () {
return new FileLogger();
});
// 在使用时
$logger1 = app(LoggerInterface::class);
$logger2 = app(LoggerInterface::class);
var_dump($logger1 === $logger2); // 输出:false (两个不同的实例)
如何变成单例?
如果你希望容器只创建一次实例,后续都返回同一个,你需要使用 singleton 方法。
示例 1:使用 singleton
$this->app->singleton(LoggerInterface::class, function () {
return new FileLogger();
});
$logger1 = app(LoggerInterface::class);
$logger2 = app(LoggerInterface::class);
var_dump($logger1 === $logger2); // 输出:true (同一个实例)
示例 2:使用 instance(直接注入已存在的对象)
$logger = new FileLogger(); $this->app->instance(LoggerInterface::class, $logger); $logger1 = app(LoggerInterface::class); $logger2 = app(LoggerInterface::class); var_dump($logger1 === $logger2); // 输出:true
常见的单例案例
Laravel 框架中很多核心服务确实使用了单例模式,但这是框架自己显式注册的,不是容器默认行为。
| 服务 | 绑定方式 |
|---|---|
app (容器本身) |
本身就是单例 |
config |
单例 |
request |
单例(在同一个 HTTP 请求生命周期内) |
db (数据库连接) |
单例(同一个连接复用) |
cache |
单例 |
view (视图工厂) |
单例 |
| 场景 | 行为 |
|---|---|
默认 bind() |
每次解析返回新实例 |
显式 singleton() |
只创建一次,后续复用 |
| 自动注入(无须绑定) | 每次解析返回新实例(除非该类本身被定义为单例) |
框架核心服务(如 app, config) |
显式注册为单例 |
Laravel 容器默认不是单例,只有当你主动使用 singleton、instance 或框架本身显式注册了单例时,它才是单例。