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

Quarkus如何加载多配置创建同一Java配置类的多个实例?

在Quarkus中批量映射多组配置为同一接口实例

问题背景

现有.properties配置文件内容如下:

test1.name=test1
test1.url=www.test.com

test2.name=test2
test2.url=www.test2.com

当前通过创建多个继承自Generic的子接口并分别标注@ConfigMapping实现配置映射,但配置组数量较多时需创建大量重复接口,希望找到更简洁的实现方式。

解决方案1:使用@ConfigMapping集合映射(推荐)

Quarkus的@ConfigMapping支持直接将同前缀格式的配置映射为同类型实例的集合,无需定义多个子接口,有两种适配方式:

适配原有配置结构

直接基于现有配置格式定义顶层映射接口:

public interface Generic {
    String name();
    String url();
}

@ConfigMapping(prefix = "") // 根前缀匹配所有test*开头的配置项
public interface AllConfigs {
    // "test"会匹配test1、test2这类前缀,Map的key为1、2,对应值为Generic实例
    Map<String, Generic> test();
}

优化配置结构(更推荐)

将配置调整为层级化格式,可读性更强:

tests.test1.name=test1
tests.test1.url=www.test.com

tests.test2.name=test2
tests.test2.url=www.test2.com

对应接口定义:

public interface Generic {
    String name();
    String url();
}

@ConfigMapping(prefix = "tests")
public interface AllConfigs {
    // Map的key为test1、test2,直接对应配置中的二级前缀
    Map<String, Generic> test();
}

使用方式

注入AllConfigs即可获取所有实例:

@Inject
AllConfigs allConfigs;

// 获取单个实例
Generic test1 = allConfigs.test().get("test1");
Generic test2 = allConfigs.test().get("test2");

解决方案2:改进CDI生产者(避免重复代码)

如果不想调整配置结构,可通过CDI生产者结合循环逻辑批量生成实例,无需手动编写多个生产者方法:

public interface Generic {
    String name();
    String url();
}

@Dependent
public class ConfigProducer {
    // 定义需要映射的配置前缀列表
    private static final List<String> CONFIG_PREFIXES = List.of("test1", "test2");

    @Produces
    @ApplicationScoped
    public Map<String, Generic> produceAllGenerics(Config config) {
        Map<String, Generic> instances = new HashMap<>();
        for (String prefix : CONFIG_PREFIXES) {
            // 用Quarkus Config API直接构建Generic实例
            Generic instance = config.getValue(prefix, Generic.class);
            instances.put(prefix, instance);
        }
        return instances;
    }
}

使用方式

注入Map<String, Generic>直接通过key获取对应实例:

@Inject
Map<String, Generic> genericMap;

Generic test1 = genericMap.get("test1");

解决方案3:自定义配置读取(灵活度最高)

如果需要更精细的控制逻辑,可直接使用Quarkus的Config API手动读取配置并构建实例:

// 实现Generic接口的实体类
public class GenericImpl implements Generic {
    private final String name;
    private final String url;

    public GenericImpl(String name, String url) {
        this.name = name;
        this.url = url;
    }

    @Override
    public String name() {
        return name;
    }

    @Override
    public String url() {
        return url;
    }
}

@ApplicationScoped
public class CustomConfigLoader {
    @Inject
    Config config;

    public Map<String, Generic> loadAllGenerics() {
        Map<String, Generic> instances = new HashMap<>();
        // 遍历所有配置键,匹配test*前缀的配置项
        for (Config.Key key : config.getPropertyNames()) {
            String keyStr = key.getName();
            if (keyStr.startsWith("test") && keyStr.contains(".name")) {
                String prefix = keyStr.split("\\.")[0];
                String name = config.getValue(prefix + ".name", String.class);
                String url = config.getValue(prefix + ".url", String.class);
                instances.put(prefix, new GenericImpl(name, url));
            }
        }
        return instances;
    }
}

使用方式

注入配置加载器并调用方法获取实例:

@Inject
CustomConfigLoader configLoader;

Map<String, Generic> genericMap = configLoader.loadAllGenerics();
Generic test1 = genericMap.get("test1");

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.15 19:27:35