【问题标题】:Can I use compileOnly as a replacement for annotationProcessor in gradle?我可以使用 compileOnly 作为 gradle 中的 annotationProcessor 的替代品吗?
【发布时间】:2018-04-23 18:31:47
【问题描述】:

我目前对注解处理器的理解是,它指的是预解析文件以查找某些注解,并以此为基础生成或更改其他代码的代码。它发生在项目的常规编译阶段之前。

在 gradle 中,我们通常使用 apt、kpt - 我有时看到使用 annotationProcessor - 表示在“注释处理时间”需要一些依赖。

如果以上理解正确,compileOnly 与 apt、kpt 等有何不同?

【问题讨论】:

  • 我觉得annotationProcessor只能生成代码,不能修改

标签: gradle


【解决方案1】:

正如您所说,Gradle 中有几个注释处理解决方案:

  1. annotationProcessor Android 设施
  2. apt 用于纯 Java 和 Groovy
  3. kapt Kotlin

等等。你甚至可以自己实现一个!它们都使用单独的configuration 进行注释处理。

确实,其中一些曾经使用compile 类路径进行处理。但这在语义上不正确,它不是“Gradle 方式”。您不应将仅编译 time 的依赖项与应用程序 run 所需的工件混合。我能想到的一个简单场景是创建胖 JAR:很可能您不想打包和运送您使用过的处理器,因为这没有任何意义!可能还有其他情况。

由于 Gradle 的灵活性,您可以做的是创建另一个类路径 (configuration) 并将其仅用于注释处理,然后就忘记它们。这是一种语义:您是在告诉 Gradle(和其他开发人员),您的应用程序运行不需要这些依赖项。这就是compileOnlyapt 不同的地方:compileOnly 依赖项是代码运行所必需的,但它们应该由环境提供。它会是您的应用程序服务器,还是插件主机系统,甚至您会手动将它们添加到类路径中 - 它们只会在您的运行时存在,因此您不应该将它们与您的可分发包一起打包。但它们是您的代码运行所必需的。 compileOnly 依赖项的一些示例是 Servlet API(您的类显然扩展并使用它们,但它将由服务器提供)或者,如果您正在编写 Jenkins 插件,Jenkins 核心 API(您的插件将安装在该核心已经存在的詹金斯)。 JDK 本身也有点像compileOnly。相反,注释处理器根本不打算在运行时使用。它们不会存在于类路径中,也不需要它们来运行您的应用程序:它们已经生成了一些稍后编译的代码。

“混合”配置的其他含义是性能。让我引用 Android 的文档:

在以前版本的插件中,编译类路径的依赖项会自动添加到处理器类路径中。也就是说,您可以将注释处理器添加到编译类路径,它会按预期工作。但是,这会给处理器添加大量不必要的依赖项,从而对性能产生重大影响。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-09-26
    • 2018-04-09
    • 2011-07-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多