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

为何无法使用Spring的@Value注解注入自定义POJO实例?

问题原因

@Value 注解原生仅支持基础类型、包装类型、字符串、数组、基础集合类型的注入,本身不具备将结构化配置自动绑定到自定义POJO的能力。你之前可以成功注入HashMap<String, TcpServerSpec>是Spring Boot @ConfigurationProperties的绑定能力提供的支持,并非@Value原生功能。

另外你的测试代码存在两处错误:

  • @ConfigurationProperties 注解加在测试类上不会生效,该注解需要标注在配置类或待绑定的POJO类上才会触发配置绑定逻辑
  • @TestPropertySource 默认不支持YAML格式配置文件的加载,需要额外指定YAML解析工厂才能正常读取yml内容
可行解决方案

方案1:统一配置绑定类(最推荐)

定义专门的配置绑定类,统一管理所有TCP服务规格实例:

import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Configuration;
import java.util.Map;

@Configuration
@ConfigurationProperties(prefix = "com.harry.potter")
public class TcpServerConfig {
    private Map<String, TcpServerSpec> sockets;

    // getters and setters
    public Map<String, TcpServerSpec> getSockets() {
        return sockets;
    }

    public void setSockets(Map<String, TcpServerSpec> sockets) {
        this.sockets = sockets;
    }
}

需要使用时直接注入配置类,按需获取对应实例即可:

@Autowired
private TcpServerConfig tcpServerConfig;

// 取单个实例
TcpServerSpec server1 = tcpServerConfig.getSockets().get("server1");

方案2:单独绑定单个POJO

如果仅需要使用单个服务规格实例,可以直接给对应POJO加绑定注解:

@Configuration
@ConfigurationProperties(prefix = "com.harry.potter.sockets.server1")
public class Server1Spec extends TcpServerSpec{
}

注入时直接注入这个类的实例即可:

@Autowired
private Server1Spec server1;

测试代码修正

如果要在测试类中加载YAML配置,需要自定义YAML属性源工厂:

import org.springframework.boot.env.YamlPropertySourceLoader;
import org.springframework.core.env.PropertySource;
import org.springframework.core.io.support.DefaultPropertySourceFactory;
import org.springframework.core.io.support.EncodedResource;
import java.io.IOException;
import java.util.List;

public class YamlPropertySourceFactory extends DefaultPropertySourceFactory {
    @Override
    public PropertySource<?> createPropertySource(String name, EncodedResource resource) throws IOException {
        List<PropertySource<?>> sources = new YamlPropertySourceLoader().load(resource.getResource().getFilename(), resource.getResource());
        return sources.get(0);
    }
}

测试类上的@TestPropertySource指定工厂即可:

@TestPropertySource(locations = "classpath:application-test1.yml", factory = YamlPropertySourceFactory.class)

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.06 14:24:04