我目前对注释处理器的理解是,它指的是预先解析文件以查找某些注释,生成或更改其他代码的代码。它发生在项目的常规编译阶段之前。
在gradle中我们通常使用apt,kpt - 我有时会看到使用annotationProcessor
- 表示在“注释处理时间”需要一些依赖关系。
如果上面的理解是正确的,那么compileOnly
与apt,kpt等有何不同?
答案 0 :(得分:4)
正如您所说,Gradle中有几个注释处理解决方案:
annotationProcessor
适用于Android的设施apt
用于纯Java和Groovy kapt
代表Kotlin 等等。你甚至可以自己实现一个!所有这些都使用单独的configuration
进行注释处理。
compile
类路径进行处理。但这不是语义更正,它不是“Gradle方式”。您不应该将编译时间仅依赖项与应用程序运行所需的工件混合在一起。我能想到的一个简单场景是创建胖JAR:很可能你不想打包和运送你使用过的处理器,因为它没有意义!可能还有其他情况。
由于Gradle的灵活性,您可以做的是创建另一个类路径(configuration
)并仅将其用于注释处理,然后忘记它们。它是一种语义:您告诉Gradle(和其他开发人员)您运行应用程序不需要这些依赖项。这是compileOnly
与apt
不同的地方:compileOnly
依赖关系是您运行代码所必需的,但它们应由环境提供 。它是您的应用程序服务器,还是插件主机系统,甚至您将手动将它们添加到类路径中 - 它们只会存在您的运行时,因此您不应将它们与您的可分发包装在一起。但是他们需要运行您的代码。 compileOnly
依赖项的一些示例是Servlet API(您的类显然扩展并使用它们,但它将由服务器提供),或者,如果您正在编写Jenkins插件,则Jenkins核心API(您的插件将被安装)在詹金斯,那个核心已经存在)。 JDK本身也是compileOnly
。相反,注释处理器根本不打算在运行时使用。它们不会存在于类路径中,并且它们不需要运行您的应用程序:它们已经生成了一些稍后编译的代码。
“混合”配置的其他含义是性能。让我引用Android的文档:
在以前版本的插件中,编译类路径的依赖关系会自动添加到处理器类路径中。也就是说,您可以将一个注释处理器添加到编译类路径中,它将按预期工作。但是,这会通过向处理器添加大量不必要的依赖性而对性能产生重大影响。