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

自定义Spring PropertySourceLoader解析的TOML配置值未生效如何解决

问题根因

你当前的实现核心问题在于Jackson将TOML解析后返回的是嵌套层级的Map结构,而Spring Boot的属性绑定逻辑要求PropertySource中存储的是扁平格式的配置Key,例如server.port、myapp.foo这种用点分隔的字符串作为Key,而非嵌套的server对应子Map的结构,因此Spring无法匹配到对应的属性值,导致所有配置都不生效。

解决方案

你需要在解析得到嵌套Map后,将其递归扁平化为带点分隔符的单层Map,再传入OriginTrackedMapPropertySource即可。

修复后的核心代码

public final class TomlPropertySourceFactory implements PropertySourceFactory {

    @Override
    public PropertySource<?> createPropertySource(String name, EncodedResource resource) throws IOException {
        if (!ClassUtils.isPresent("com.fasterxml.jackson.dataformat.toml.TomlFactory", null)) {
            throw new IllegalStateException(
                    "Attempted to load " + name + " but jackson-dataformat-toml was not found on the classpath");
        }
        if (!ClassUtils.isPresent("com.fasterxml.jackson.core.io.ContentReference", null)) {
            throw new IllegalStateException(
                    "Attempted to load " + name + " but jackson-core was either not found on the classpath or below version 2.13.0");
        }
        final ObjectMapper mapper = new ObjectMapper(new TomlFactory());
        final Map<String, Object> nestedMap = mapper.convertValue(mapper.readTree(resource.getInputStream()), new TypeReference<Map<String, Object>>(){});
        // 扁平化处理嵌套Map
        Map<String, Object> flatMap = new HashMap<>();
        flattenMap(nestedMap, "", flatMap);
        return new OriginTrackedMapPropertySource(Optional.ofNullable(name).orElseGet(resource.getResource()::getFilename), flatMap);
    }

    /**
     * 递归扁平化嵌套Map,生成带点分隔的Key
     */
    private void flattenMap(Map<String, Object> source, String prefix, Map<String, Object> target) {
        source.forEach((key, value) -> {
            String currentKey = prefix.isEmpty() ? key : prefix + "." + key;
            if (value instanceof Map) {
                @SuppressWarnings("unchecked")
                Map<String, Object> subMap = (Map<String, Object>) value;
                flattenMap(subMap, currentKey, target);
            } else {
                // 基础类型、集合类型直接存储,Spring属性绑定可自动适配对应格式
                target.put(currentKey, value);
            }
        });
    }
}

你原有TomlPropertySourceLoader的逻辑不需要修改,重启应用后server.port、@ConfigurationProperties注入都会正常生效。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.05 07:30:04