如何使用Dagger重构32个继承同一抽象类的子类的依赖注入
解决方案
方案1:使用Dagger原生多绑定机制(推荐)
Dagger官方提供了多绑定能力,专门用于注入同接口/父类的多个实现实例,完全解决当前手动罗列32个参数的臃肿问题,实现步骤如下:
- 为每个
ParentClass的子类添加绑定配置,使用@Binds+@IntoSet注解将子类实例注册到全局ParentClass实例集合中,示例代码:
@Module public abstract class SubClassAModule { @Binds @IntoSet @Singleton // 若需要子类为单例则添加该注解,和普通绑定规则一致 public abstract ParentClass bindSubClassA(SubClassA impl); }
每个子类只需独立编写对应绑定模块,新增/删除子类时仅需新增/删除对应模块即可,无需修改ClassManager相关逻辑。
2. 调整ClassManager的注入逻辑,直接接收Dagger自动聚合的Set<ParentClass>即可:
public class ClassManager { private List<ParentClass> all = new ArrayList<>(); @Inject public ClassManager(Set<ParentClass> classes) { all.addAll(classes); } // 其余原有方法保持不变 }
- 删除原有的手动罗列所有子类参数的
provideClassManager方法,Dagger会自动将所有通过@IntoSet注册的ParentClass实现聚合为Set注入到ClassManager中。
如果后续需要按类型获取特定子类实例,可改用@MapKey多绑定方案,将所有实例按自定义key聚合为Map注入,使用更灵活。
方案2:搭配注解处理器进一步简化绑定流程
如果需要省略每个子类的绑定模块编写,可以自定义轻量注解处理器:
- 定义自定义注解如
@ParentComponent,标注所有ParentClass的子类 - 注解处理器在编译期扫描所有带该注解的类,自动生成对应的
@Binds @IntoSet绑定代码,完全无需手动编写绑定模块
可选替代库方案
如果接受运行时注入的开销,也可以选择以下库:
- Guice:支持包扫描自动绑定,无需手动编写绑定配置,适合对启动速度要求不高的场景
- Spring Context 轻量版:功能更丰富,同样支持注解扫描自动注册Bean,但性能开销高于Dagger
内容的提问来源于stack exchange,提问作者Mangu
相关产品推荐
相关产品推荐

