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

Spring Boot读取YAML文件至子类时属性为null,求排查

问题分析与解决方案

你的代码存在基础类结构错误、YAML与Java对象映射不匹配、Spring配置方式不当三类核心问题,以下是具体修正步骤:

1. 修复类实现与构造函数的基础错误

首先,你的LiteralExpression和FunctionExpression未实现Expression接口,且构造函数存在笔误,这是Spring无法识别实例类型的核心原因:

修正后的LiteralExpression

public class LiteralExpression implements Expression {
    private final String literal;

    public LiteralExpression(String literal) {
        this.literal = literal; // 修复原代码中this.value的错误赋值
    }

    @Override
    public String evaluate() {
        return literal;
    }
}

修正后的FunctionExpression

public class FunctionExpression implements Expression {
    private final String name;
    private final Expression[] params;

    // 修复构造函数类名写错的问题,以及this.value的错误赋值
    public FunctionExpression(String name, Expression... params) {
        this.name = name;
        this.params = params;
    }

    @Override
    public String evaluate() {
        return Functions.getFunction(name).apply(
            Stream.of(params)
                .map(Expression::evaluate)
                .toArray(String[]::new)
        );
    }
}

2. 解决多态对象的YAML映射问题

Spring无法自动识别YAML中的literal/function字段对应的具体子类,需要添加类型标识并配置Jackson注解:

修改YAML文件,添加类型标识

expressions:
  - expression:
      type: literal
      literal: hello
  - expression:
      type: function
      name: add
      params:
        - expression:
            type: literal
            literal: 1
        - expression:
            type: literal
            literal: 2

给Expression接口添加Jackson多态注解

import com.fasterxml.jackson.annotation.JsonSubTypes;
import com.fasterxml.jackson.annotation.JsonTypeInfo;

@JsonTypeInfo(
    use = JsonTypeInfo.Id.NAME,
    include = JsonTypeInfo.As.PROPERTY,
    property = "type" // 对应YAML中的type字段
)
@JsonSubTypes({
    @JsonSubTypes.Type(value = LiteralExpression.class, name = "literal"),
    @JsonSubTypes.Type(value = FunctionExpression.class, name = "function")
})
public interface Expression {
    String evaluate();
}

3. 调整Spring配置类与解析方式

你当前用YamlPropertySourceFactory将YAML转成扁平的Properties,会丢失多态结构信息,应改用Spring Boot原生的YAML解析方式:

移除@PropertySource,引入自定义YAML文件

在application.yaml中添加配置,引入你的自定义YAML文件:

spring:
  config:
    import: classpath:expressions.yaml

修正配置类,添加包装类匹配YAML结构

由于YAML中每个元素都包含expression键,需要用包装类承接,避免直接用List<Expression>无法匹配结构:

@Component
@ConfigurationProperties
@NoArgsConstructor
@Data
public class ProfileConfig { // 修复原类名ProfielConfig的拼写错误
    private List<ExpressionWrapper> expressions;

    // 包装类匹配YAML中的expression键结构
    @Data
    @NoArgsConstructor
    public static class ExpressionWrapper {
        private Expression expression;
    }
}

4. 确保构造函数可被Spring实例化

Spring需要无参构造函数或通过@ConstructorBinding指定构造函数,给子类添加Lombok注解:

@AllArgsConstructor // 替代手动写带参构造函数
public class LiteralExpression implements Expression {
    private final String literal;

    @Override
    public String evaluate() {
        return literal;
    }
}
@AllArgsConstructor
public class FunctionExpression implements Expression {
    private final String name;
    private final Expression[] params;

    @Override
    public String evaluate() {
        return Functions.getFunction(name).apply(
            Stream.of(params)
                .map(Expression::evaluate)
                .toArray(String[]::new)
        );
    }
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.11 07:31:20