如何让自定义库的annotationProcessor具备传递性?
问题场景
我正在用自研的自定义Starter库给微服务产品配置核心依赖。为了让依赖能自动传递给继承的项目,我在库里用了Gradle的api(dependency),示例代码如下:
api(libs.bundles.util) // 依赖别名来自version-catalog
现在想知道有没有办法让annotationProcessor()作用域也像api()一样具备传递性,期望能有类似这样的写法:
apiAnnotationProcessor(libs.mapstruct.processor) // 希望mapstruct和lombok的处理器能自动传递
解答
Gradle本身没有提供apiAnnotationProcessor这类内置配置来让注解处理器具备传递性,核心原因是:
Gradle的annotationProcessor配置被设计为模块私有,仅作用于当前模块的编译过程,不会自动传递给依赖它的模块。这是因为注解处理器的执行和模块编译强绑定,强制传递可能导致依赖模块出现意外的代码生成、版本冲突或编译错误,不符合Gradle的依赖隔离设计理念。
不过可以通过以下几种方式实现类似效果:
自定义可传递配置
在你的Starter库的build.gradle中定义一个可被消费的自定义配置,将注解处理器依赖加入其中:configurations { apiAnnotationProcessor { canBeConsumed = true canBeResolved = false extendsFrom annotationProcessor } } dependencies { apiAnnotationProcessor libs.mapstruct.processor apiAnnotationProcessor libs.lombok }然后在依赖该Starter的项目中,手动将这个配置导入到自身的
annotationProcessor:dependencies { api project(':your-custom-starter') annotationProcessor configurations.apiAnnotationProcessor }通过apiElements暴露处理器(不推荐)
如果你的Starter使用java-library插件,可以尝试将注解处理器的JAR包附加到apiElements变体中,让依赖模块能获取到:configurations.apiElements.outgoing.variants.getByName('apiElements').artifact( file: configurations.annotationProcessor.files, type: 'jar' )这种方式属于hack手段,容易引发依赖冲突和不可预期的编译问题,不建议作为长期方案。
文档提示手动添加
最稳妥的方式是在Starter的文档中明确说明,依赖该Starter的项目需要手动添加对应的注解处理器依赖,比如:annotationProcessor libs.mapstruct.processor annotationProcessor libs.lombok虽然需要手动操作,但能避免传递带来的潜在问题,也更贴合Gradle的设计原则。
内容的提问来源于stack exchange,提问作者Jake Zubarev

