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

Dagger中模块无作用域绑定覆盖构造函数注入单例绑定的原因探究

为什么Dagger选择了AppModule的无作用域绑定而非Foo的@Singleton构造注入?

这个现象本质是Dagger的绑定优先级规则在起作用,咱们来一步步拆解原因:

1. 显式@Provides方法优先级高于@Inject构造函数

Dagger在解析依赖实例的时候,有一套明确的绑定选择顺序,优先级从高到低是:

  • 模块中显式定义的@Provides(或@Binds)方法
  • 类本身带有@Inject注解的构造函数
  • 通过@BindsInstance提供的实例

你的代码里,AppModule中的provideFoo()是一个显式的@Provides绑定,所以Dagger会直接优先选用这个方法来创建Foo实例,完全跳过了Foo类本身带@Singleton的@Inject构造函数——这就是为什么生成的代码里没有用到DoubleCheck(Dagger实现单例的核心逻辑)。

2. 作用域注解的生效前提

Foo构造函数上的@Singleton注解,只有当Dagger通过这个构造函数来创建实例的时候才会生效。但因为模块的@Provides方法抢了优先级,Dagger根本不会去调用这个构造函数,自然也就不会应用单例的逻辑了。

3. 如何调整达到预期效果

如果你想让Foo以单例形式被提供,有两种方式:

  • 删掉AppModule中的provideFoo()方法,让Dagger使用Foo类的@Inject构造函数,此时@Singleton注解会生效,生成的代码会包含DoubleCheck逻辑
  • 给AppModule中的provideFoo()方法也加上@Singleton注解,这样Dagger会用这个方法创建单例实例,同样会生成单例相关的代码

附上你的示例代码:

@Module
public class AppModule {
    @Provides
    public Foo provideFoo() {
        return new Foo();
    }
}

@Component(module = AppModule.class)
@Singleton
public interface AppComponent {
    Foo getFoo();
}

@Singleton
class Foo @Inject constructor(){
    //..
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.30 20:33:12