我试图弄清楚在构建依赖关系时api和实现配置之间的区别。

在文档中,它说实现有更好的构建时间,但是,在一个类似的问题中看到这个评论,我想知道这是否是真的。

因为我不是Gradle的专家,我希望有人能帮助我。我已经阅读了文档,但我想知道一个简单易懂的解释。


当前回答

文档中有很好的解释

api配置应该用于声明依赖关系 由库API导出,而实现配置 应用于声明依赖项,这些依赖项是 组件。

其他回答

关于api和实现还有一个技术注意事项。假设你有以下依赖项:

dependencies {
  api "com.example:foo:1.0"
  implementation "com.example:bar:1.0"
}

如果你在本地Maven存储库中安装了一个生成的jar文件(借助Maven -publish插件),你会看到生成的pom.xml文件如下所示:

    <dependency>
      <groupId>com.example</groupId>
      <artifactId>foo</artifactId>
      <version>1.0</version>
      <scope>compile</scope>
    </dependency>
    <dependency>
      <groupId>com.example</groupId>
      <artifactId>bar</artifactId>
      <version>1.0</version>
      <scope>runtime</scope>
    </dependency>

注意:api被转换为编译作用域和实现到运行时作用域。

这允许这个库的使用者避免在他们的编译类路径中有运行时依赖项。

来自gradle文档:

让我们看一下基于jvm的项目的一个非常简单的构建脚本。

plugins {
    id 'java-library'
}

repositories {
    mavenCentral()
}

dependencies {
    implementation 'org.hibernate:hibernate-core:3.6.7.Final'
    api 'com.google.guava:guava:23.0'
    testImplementation 'junit:junit:4.+'
}

实现 编译项目的生产源代码所需的依赖项,这些依赖项不是项目公开的API的一部分。例如,该项目使用Hibernate进行内部持久层实现。 api 编译项目生产源代码所需的依赖项,这些依赖项是项目公开的API的一部分。例如,该项目使用了Guava,并在方法签名中公开了带有Guava类的公共接口。

文档中有很好的解释

api配置应该用于声明依赖关系 由库API导出,而实现配置 应用于声明依赖项,这些依赖项是 组件。

假设你有一个应用模块,它使用lib1作为库,lib1使用lib2作为库。就像这样:app -> lib1 -> lib2。

现在当在lib1中使用api lib2时,当在app模块中使用api lib1或实现lib1时,app可以看到lib2代码。

但是当在lib1中使用实现lib2时,应用程序无法看到lib2代码。

我喜欢把api依赖看作是公共的(其他模块可以看到),而实现依赖则是私有的(只有这个模块可以看到)。

注意,与公共/私有变量和方法不同,api/实现依赖关系不是由运行时强制执行的。这只是一个构建时优化,它允许Gradle知道当某个依赖项更改API时需要重新编译哪些模块。