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

Dagger2自定义Scope疑问:带@MyScope的类用Provider为何不返回单例?

Dagger2中Scope注解在Provider方法与构造注入场景的差异解析

核心逻辑:Scope绑定的是「实例提供者」,而非目标类本身

Dagger2的Scope注解生效的核心是标记「谁来提供实例」,以及这个提供者产出的实例要在哪个Scope的组件生命周期内被缓存,而非直接绑定到你要注入的类上——这就是两种场景出现差异的根本原因。

场景1:使用Module的Provider方法提供实例时,类上的@MyScope不生效

当你在ToastMakerModule中通过@Provides方法提供ToastMaker实例时:

  • Dagger会优先以这个Provider方法作为实例的唯一来源,完全忽略类上的@Inject构造和@MyScope注解
  • 若不给该Provider方法添加@MyScope,Dagger会默认将其视为「无Scope的提供者」,每次注入都会调用方法生成新实例,因此两次注入的哈希码不同
  • 此时类上的@MyScope只是一个无意义的标记,因为Dagger不会通过构造注入的路径创建该类实例

场景2:使用构造注入时,类上的@MyScope生效

当你删除Provider方法,改用@Inject构造注入时:

  • Dagger会读取类上的@MyScope注解,结合组件ActionsComponent上的同Scope注解,识别出该类实例属于@MyScope的生命周期
  • Dagger会将首次生成的ToastMaker实例缓存到当前@MyScope对应的组件容器中,后续所有注入请求都会直接返回缓存实例,因此两次注入的哈希码相同

为什么给Provider方法加@MyScope就能解决问题?

给Provider方法加上@MyScope后,相当于告诉Dagger:「这个方法产出的实例,要和标注了@MyScope的组件生命周期绑定,在组件存活期间只生成一次并缓存」。此时Dagger会将该Provider方法的产出纳入Scope缓存机制,自然多次注入都会拿到同一个实例。

总结

  • Scope注解的作用对象是实例的提供者:要么是@Provides方法,要么是@Inject构造函数
  • 类上的Scope注解仅在构造注入场景生效,当有Provider方法覆盖实例创建路径时,类上的标记会被忽略
  • 要让Scope生效,必须保证「提供者(Provider方法/构造)的Scope」与「组件的Scope」完全匹配

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.11 05:32:24