You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Quarkus Maven打包阶段检测Bean注入点引发依赖不满足问题排查

问题分析

打包阶段出现UnsatisfiedResolutionException的核心原因有两个:

  1. DevServices在打包阶段默认不激活:quarkus dev模式下DevServices会自动启动容器并生成DevServicesResultBuildItem,但执行mvn package时DevServices默认关闭,你的createConfigBean BuildStep因找不到DevServicesResultBuildItem抛出异常,导致SyntheticBeanBuildItem未生成,CDI验证时找不到FooConfig Bean。
  2. FooConfig的@ApplicationScoped注解冲突:你通过SyntheticBeanBuildItem提供Bean,但FooConfig标注了@ApplicationScoped,CDI会尝试扫描并实例化它,而你的无参构造是私有,CDI无法完成实例化,进一步加剧了依赖解析失败。
解决方案

1. 移除FooConfig的@ApplicationScoped注解

因为你完全通过SyntheticBeanBuildItem提供FooConfig实例,不需要CDI自动扫描这个类,移除注解避免冲突:

/**
* Bean to inject
*/
// 移除@ApplicationScoped
public class FooConfig {

    private String url;
    private String port;

    // Only for CDI injection
    @SuppressWarnings("unused")
    private FooConfig() {}

    public FooConfig(String url, String port) {
        this.url = url;
        this.port = port;
    }

    // getter/setter 保持不变
}

2. 添加Build Time配置作为打包阶段 fallback

为扩展添加Build Time配置属性,当打包阶段DevServices未启动时,使用默认配置生成FooConfig:
首先创建配置属性类:

import io.quarkus.runtime.annotations.ConfigRoot;
import io.smallrye.config.ConfigItem;
import io.quarkus.runtime.configuration.ConfigPhase;

@ConfigRoot(name = "foo", phase = ConfigPhase.BUILD_TIME)
public class FooBuildConfig {
    @ConfigItem(defaultValue = "localhost:8080")
    public String apiUrl;
}

3. 修改BuildStep处理无DevServices的场景

修改createConfigBean BuildStep,兼容DevServices未启动的情况,使用配置属性生成Bean:

@Record(ExecutionTime.RUNTIME_INIT)
@BuildStep
public void createConfigBean(
        @Optional List<DevServicesResultBuildItem> devServicesResults,
        FooRecorder recorder,
        BuildProducer<SyntheticBeanBuildItem> beanProducer,
        FooBuildConfig buildConfig
) {
    String apiUrl;
    // 优先使用DevServices提供的地址
    if (devServicesResults != null && !devServicesResults.isEmpty()) {
        apiUrl = devServicesResults.stream()
                .filter(r -> r.getName().equals(FooServiceContainer.CONTAINER_NAME))
                .findFirst()
                .orElseThrow(() -> new IllegalStateException("Can't find foo-service url"))
                .getConfig().get("url");
        apiUrl = "http://" + apiUrl;
    } else {
        // 打包阶段使用Build Time配置
        apiUrl = "http://" + buildConfig.apiUrl;
    }
    // 修正端口分割逻辑:http://localhost:8080 分割后索引2为端口
    String port = apiUrl.split(":")[2];
    beanProducer.produce(SyntheticBeanBuildItem.configure(FooConfig.class)
            .unremovable()
            .setRuntimeInit()
            .runtimeValue(recorder.createConfig(apiUrl, port))
            .done());
}

4. 调整Recorder方法

确保Recorder的createConfig方法参数正确,避免端口处理错误:

@Recorder
public class FooServiceRecorder {

    public RuntimeValue<FooConfig> createConfig(String url, String port) {
        return new RuntimeValue<>(new FooConfig(url, port));
    }
}
验证

修改后执行mvn package,Quarkus会使用Build Time配置生成FooConfig Bean,CDI验证通过;运行quarkus dev时,依然会优先使用DevServices提供的地址,保持原有功能。

内容的提问来源于stack exchange,提问作者Scandinave

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.22 00:22:34