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

Dagger2公共Module引入已公开Module仍报非公开错误如何解决?

问题排查与解决方案

该报错本质是Dagger的可见性检测逻辑判定被引入的ModuleA对ModuleB无效,即使你声明了public修饰符,可优先排查以下容易忽略的场景:

  • 确认ModuleA是顶级public类,不是嵌套在其他类中的非public内部类,如果是嵌套类需要额外添加static+public修饰,否则默认是包私有可见。
  • 若项目使用了Java 9+的JPMS模块化系统,需要在ModuleA所在JPMS模块的module-info.java中,将ModuleA所在的包export给Dagger注解处理器和ModuleB所在的模块,否则即使类加了public,JPMS也会限制跨模块访问。
  • 若是多Gradle模块项目,确认ModuleB的build.gradle中正确依赖了ModuleA所在的Gradle模块,不要使用runtimeOnly这类仅运行时生效的依赖声明。

如果以上排查均无问题,可以直接添加注解属性绕过Dagger的可见性校验:给ModuleA的@Module注解添加visible = true属性,明确告知Dagger该模块对外可见,修改后代码如下:

@Module(visible = true)
public class ModuleA {

    @Provides
    @Singleton
    @Named("classA")
    public ClassA classA() {
        return new ClassA();
    }
}

修改后重新编译即可消除报错。


最佳实践优化建议

你当前的基础写法符合Dagger的使用规范,针对你的场景(ModuleA仅被ModuleB内部引用,不对外暴露)可以做以下优化:

  • 既然ModuleA不需要对外公开,可以直接去掉public修饰符改为包私有,仅保留@Module(visible = true)即可,避免对外暴露不必要的内部实现。
  • 建议将@Named("classA")替换为自定义@Qualifier注解,比字符串形式的Named更安全,编译阶段即可检测出拼写错误,示例如下:
@Qualifier
@Retention(RetentionPolicy.RUNTIME)
public @interface InternalClassA {}

替换后ModuleA的@Provides方法和ModuleB的注入点都改用@InternalClassA修饰即可。

  • 两个Module都使用了@Singleton作用域,需要确保引用ModuleB的Component也标注了@Singleton,否则会出现作用域不匹配的错误。
  • 如果后续没有其他模块需要复用ModuleA的提供逻辑,可以直接把ClassA的提供方法合并到ModuleB中,减少不必要的Module拆分,降低维护成本。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.14 03:39:04