Dagger中@Inject注解类是否可充当Provider?及组件注入疑问
嘿,我来帮你理清Dagger 2.16里这些容易搞混的点,你提到的几个问题其实都是Dagger核心机制的体现,咱们一个个拆解:
1. 为啥没在Module里声明的类能被直接使用?
你观察到的RecipePresenter这种情况,核心原因是构造函数注入:如果一个类的构造函数被标注了@Inject,Dagger会自动识别这个构造函数,知道怎么创建该类的实例,完全不需要在Module里写@Provides或者@Binds。
比如RecipePresenter的代码可能是这样的:
public class RecipePresenter { private final RecipeRepository repo; // 用@Inject标注构造函数,Dagger会自动用这个构造创建实例 @Inject public RecipePresenter(RecipeRepository repo) { this.repo = repo; } }
这是Dagger最推荐的依赖提供方式,比Module里的@Provides更简洁,也更符合依赖注入的设计思想。
2. @Inject标注的类会归属到哪个组件/子组件?
你的猜测完全正确:当类有@Inject构造函数时,它会被加入Dagger的组件图中。至于归属哪个组件,规则其实很清晰:
- 无自定义Scope的类:哪个组件需要它,Dagger就会在该组件中生成对应的创建逻辑。比如如果
AppComponent和RecipeComponent都需要RecipePresenter,那两个组件都会各自创建它的实例(除非用Scope限制)。 - 有自定义Scope的类:会绑定到标注了相同Scope的组件。比如你给
RecipePresenter加了@ActivityScope,同时RecipeComponent也标注了@ActivityScope,那这个Presenter就只会归属于RecipeComponent,不会被其他组件共享。 - 子组件会继承父组件的依赖,但如果子组件有自己的Scope和Module,优先使用子组件内的规则。
3. 为啥Activity/Fragment需要手动注入,不能自动?
这是Android系统的特性决定的:
- Activity和Fragment的实例是由Android系统创建的,不是Dagger创建的。你没法给Activity的构造函数加
@Inject——系统只会调用无参构造函数,不会管你自定义的带参数构造。 - Dagger只能给已经存在的实例注入依赖,所以必须手动调用
component.inject(this),把已经被系统创建好的Activity/Fragment实例传递给Dagger,让它完成成员变量的注入。 - 而像Presenter这种你自己控制生命周期的类,Dagger可以直接创建并注入依赖,因为它们的实例是由Dagger管理的,不需要系统插手。
额外小提示
- 区分两种
@Inject的作用:标注在构造函数上是告诉Dagger怎么创建这个类;标注在成员变量上是告诉Dagger要给这个变量注入依赖。 - 合理使用Scope(比如
@Singleton、@ActivityScope)不仅能避免重复创建实例,还能明确类的组件归属,让你的依赖关系更清晰。
内容的提问来源于stack exchange,提问作者dev
相关产品推荐
相关产品推荐

