
本文介绍如何让 Gradle 在同一项目中正确启用自定义注解处理器(即:在定义处理器的模块内,对其自身代码执行注解处理),解决 annotationProcessor 在本模块 src/test 中失效的问题。
本文介绍如何让 gradle 在同一项目中正确启用自定义注解处理器(即:在定义处理器的模块内,对其自身代码执行注解处理),解决 `annotationprocessor` 在本模块 `src/test` 中失效的问题。
在 Gradle 构建系统中,注解处理器(Annotation Processor)默认不会处理其所在模块自身的源码——这是由编译阶段的依赖隔离机制决定的:annotationProcessor 依赖仅作用于 消费该处理器的其他模块,而不会反向应用于当前模块的 main 或 test 源集。因此,即使你在 lib/src/test/java 中使用了 @MyAnnotation,Gradle 的 compileTestJava 任务也不会触发 MyAnnotationProcessor,导致 process() 方法静默不执行。
✅ 正确方案:模块拆分 + 跨模块注解处理
最稳定、符合 Gradle 最佳实践的解决方案是将 注解处理器实现 与 使用该处理器的测试代码 分离到两个独立的子项目(模块)中:
.
├── lib/ ← 核心模块:含 @MyAnnotation 和 MyAnnotationProcessor
│ ├── build.gradle
│ └── src/main/java/demo/...
├── test/ ← 测试模块:使用 @MyAnnotation 编写测试用例
│ ├── build.gradle
│ └── src/test/java/demo/MyAnnotationProcessorTest.java
└── settings.gradle ← 声明 include('lib', 'test')? 配置说明
settings.gradle
include 'lib', 'test'
lib/build.gradle(精简版,专注提供处理器)
plugins { id 'java-library' }
repositories { mavenCentral() }
dependencies {
implementation 'com.google.auto.service:auto-service:1.1.1'
annotationProcessor 'com.google.auto.service:auto-service:1.1.1'
}
java.toolchain.languageVersion = JavaLanguageVersion.of(17)✅ 注意:
lib模块不再包含测试逻辑,也不需配置testImplementation或useJUnitPlatform。
test/build.gradle(专用于验证处理器行为)
Miller (mlr) 是一个命令行工具,用于查询、整形和重新格式化名称索引数据,如 CSV、TSV、JSON 和 JSON Lines。它将 awk、sed、cut、join 和 sort 的功能整合到一个专为结构化数据处理而构建的单一工具中。
plugins { id 'java' }
repositories { mavenCentral() }
dependencies {
testImplementation 'org.junit.jupiter:junit-jupiter:5.9.1'
testImplementation project(':lib') // 提供注解类和处理器类
testAnnotationProcessor project(':lib') // 关键!使注解处理器参与 test 编译
}
java.toolchain.languageVersion = JavaLanguageVersion.of(17)
tasks.test {
useJUnitPlatform()
}⚠️ 关键点:
testAnnotationProcessor project(':lib')显式声明lib作为测试期的注解处理器,确保MyAnnotationProcessor在compileTestJava阶段被激活。
✅ 验证效果
运行:
./gradlew test --info
你将在编译日志中看到:
>>>>> process called <<<<<
这表明注解处理器已成功介入测试代码的编译流程。
? 补充说明与注意事项
-
输出产物隔离:
test模块的编译结果(如test.jar)默认不会打包进lib/build/libs/xxx.jar,符合发布规范;lib的 JAR 仅含public API(注解类 + 处理器 SPI 类),不含测试代码。 -
替代方案不推荐:
- 使用
compileOnly+annotationProcessor同时依赖project(':lib')在单模块内强行复用 —— 因 Gradle 的compileJava和compileTestJava是独立任务,且annotationProcessor不跨源集生效,此方式不可靠。 - 修改
sourceSets.test.annotationProcessorPath手动注入 —— 易出错、难维护,且在新版 Gradle(8.0+)中已被弃用。
- 使用
-
进阶建议:若需集成测试(IT),可额外添加
integrationTest源集,并同样通过integrationTestAnnotationProcessor project(':lib')启用处理器。
通过模块化设计,你不仅解决了自测问题,还提前践行了“处理器应可独立发布与复用”的工程原则——这也是主流开源注解库(如 AutoService、Room、Lombok)的标准实践。

















