You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Hilt中@Binds方法上的@Singleton在依赖注入时是否生效?

@Binds搭配@Singleton的效果及Hilt警告问题

1. @Binds搭配@Singleton是否有效?

答案是:只有当实现类本身被Hilt以单例(或对应作用域)管理时,@Binds方法上的@Singleton才会生效。

@Binds的核心作用是绑定接口与实现类的映射关系,告诉Hilt:当需要TestInterface类型的实例时,返回TestInterfaceImpl的实例。而@Binds方法上的@Singleton注解,本质是要求Hilt在提供TestInterface类型实例时保证其为单例——但这个前提是,TestInterfaceImpl本身的实例是被Hilt单例化管理的。

在你的第一个场景中:

// 实现类无@Singleton注解
class TestInterfaceImpl @Inject constructor(): TestInterface{
    override fun test(){}
}

// @Binds方法标注@Singleton
@Module
@InstallIn(SingletonComponent::class)
object Module{ 
   @Singleton
   @Binds
   fun providesImplementation(testImpl: TestInterfaceImpl): TestInterface
}

由于TestInterfaceImpl没有作用域注解,Hilt每次需要创建它的实例时都会生成新对象,哪怕@Binds要求返回单例的TestInterface,底层的实现类实例还是新的,最终自然无法得到单例效果。

而当你给TestInterfaceImpl加上@Singleton后:

@Singleton
class TestInterfaceImpl @Inject constructor(): TestInterface{
    override fun test(){}
}

此时TestInterfaceImpl本身被Hilt标记为单例,每次请求都会返回同一个实例,@Binds只是把这个单例实例映射为TestInterface类型,所以最终注入的就是单例。

2. Hilt是否应抛出不必要的警告?

是的,Hilt确实应该给出警告。

当@Binds方法上的作用域注解(比如@Singleton)无法生效时(比如实现类没有匹配的作用域),Hilt的编译检查应该提示开发者:当前@Binds的作用域注解无效,因为实现类的实例管理方式不支持该作用域。

Hilt的规则是:绑定的作用域必须与组件的作用域一致,且实现类的作用域不能比绑定的作用域更窄。如果实现类没有作用域,相当于每次都创建新实例,这时候@Binds的@Singleton就违背了组件的作用域约定,Hilt应该在编译阶段抛出错误或警告,提示开发者修复这个不匹配的问题。

内容的提问来源于stack exchange,提问作者Diken Mhrz

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.14 17:13:29