Quarkus Arc多模块构建因模块未配置属性受阻问题咨询
Quarkus多模块Gradle项目构建依赖注入问题
项目背景
基于Gradle的Quarkus多模块项目,包含Core、Module1、Service1三个模块:
- Module1内有一个
@ApplicationScope类,注入了标注@DataSource("database1")的AgroalDataSource数据源 - Service1是Quarkus应用模块,负责定义
application.properties配置,为自身及依赖模块提供运行时数据源配置
报错信息
执行构建命令 gradle clean build -x test 时,出现依赖注入错误:
Unsatisfied dependency for type io.agroal.api.AgroalDataSource and qualifiers [@Default]
报错原因是Module1未包含数据源配置的application.properties,但该配置本应在Service1中定义。
核心矛盾
Quarkus Arc在构建阶段就要求解析所有注入依赖,但模块的配置本应仅在服务运行时由Service1提供,这与模块独立自治的设计逻辑冲突。
使用环境
- Gradle 8.6
- Quarkus 3.9.5
- Intellij 2024.1.1
需求说明
各模块需要包含QuarkusTest单元测试:
- 模块作为服务应用的片段,需借助Quarkus Arc实现依赖注入、启动事件等功能
- 需通过Intellij UI直接运行测试,因此模块必须配置Quarkus插件及Quarkus BOM
当前困境
模块作为Quarkus模块构建时,Arc要求构建阶段解析注入目标:
- 测试阶段可通过
TestProfile类替换配置,但构建阶段无法使用该类 - 目前只能在Module1中添加占位符
application.properties,但这不符合模块配置由应用层统一提供的设计逻辑
咨询问题
- 是否遗漏了Quarkus Arc多模块配置的相关文档?
- 如何重构项目使模块更独立自治?
- 是否必须为模块添加含占位符的
application.properties才能满足Arc的构建要求?
解决方案
问题1:关于Quarkus Arc多模块配置文档
Quarkus官方文档里明确区分了库模块和应用模块:
- 库模块(比如你的Module1)只负责提供可复用的Bean、业务逻辑,不需要包含Quarkus启动类,也不用管运行时配置
- 应用模块(也就是Service1)才是承载全局配置、启动类的地方,所有运行时配置都在这里定义
可以重点看官方文档里“多模块项目结构”和“Arc在库模块中的行为”相关内容,核心逻辑是:库模块的Bean会在构建阶段被Arc索引,但依赖的配置由应用模块提供,构建阶段只需要保证依赖的可解析性,不需要提前有完整配置。
问题2:项目重构实现模块独立自治
给你三个可行的重构方向:
方向1:把Module1改成纯库模块
- 删掉Module1里的Quarkus应用插件(
io.quarkus插件),只保留Quarkus BOM用来统一管理依赖版本 - 只在Service1里配置Quarkus插件和
application.properties - 模块里的
QuarkusTest测试,要么指定@QuarkusTest(applicationClass = Service1启动类.class),要么用TestProfile给测试单独加数据源配置,这样在IntelliJ里也能直接跑测试
方向2:用条件化Bean或间接注入绕开构建检查
- 在Module1的Bean里,给DataSource注入加条件判断,或者用Producer Bean控制数据源的创建:
@ApplicationScope public class MyService { private final AgroalDataSource dataSource; public MyService(@DataSource("database1") AgroalDataSource dataSource) { this.dataSource = dataSource; } @Produces @DataSource("database1") @ApplicationScoped public AgroalDataSource produceDataSource(AgroalDataSourceConfig config) { // 只有当配置存在时才创建数据源,构建阶段不会强制要求配置必须存在 return config.url().isPresent() ? AgroalDataSource.from(config) : null; } } - 这么做能让Arc在构建阶段不强制要求配置存在,只有运行时(或测试时)才会验证配置是否齐全
方向3:用Gradle把Quarkus插件限定在测试阶段
- 在Module1的build.gradle里,只在测试阶段启用Quarkus插件:
plugins { id 'java' id 'io.quarkus' apply false // 默认不启用 } dependencies { implementation platform('io.quarkus:quarkus-bom') implementation 'io.quarkus:quarkus-agroal' testImplementation 'io.quarkus:quarkus-junit5' testImplementation 'io.quarkus:quarkus-test-h2' } test { useJUnitPlatform() apply plugin: 'io.quarkus' // 只在测试任务里启用插件 } - 这样构建主代码时不会触发Arc的严格依赖检查,只有跑测试的时候才会启用Quarkus的相关逻辑
问题3:是否必须加占位符配置?
完全不用。通过上面的重构方案(尤其是方向1和方向2),可以彻底避免在Module1里加占位符application.properties:
- 改成纯库模块的话,构建阶段Arc不会做完整的依赖校验,只有在Service1构建时才会验证配置
- 用条件化Bean的方式,Arc在构建阶段会接受依赖的可选性,不会因为没有配置就报错
内容的提问来源于stack exchange,提问作者funkrusher
相关产品推荐
相关产品推荐

