SpringBoot中用@Value从JSON文件填充List<BigDecimal>字段的正确方法
解决SpringBoot从JSON文件加载List的问题
问题原因
直接用@Value("classpath:mockedData.json")注入List<BigDecimal>会失败,因为@Value默认把资源内容读取为字符串,Spring无法自动将JSON格式的字符串转换成List<BigDecimal>;而且Jackson的@JsonFormat、@JsonSerialize注解只在Jackson处理序列化/反序列化流程中生效,对@Value的赋值逻辑不起作用。
方法一:手动读取并解析JSON(简洁直接)
通过@Value注入Resource对象,再用Jackson的ObjectMapper手动解析成目标类型:
import org.springframework.core.io.Resource; import org.springframework.beans.factory.annotation.Value; import org.springframework.stereotype.Service; import com.fasterxml.jackson.databind.ObjectMapper; import java.io.IOException; import java.util.List; import java.math.BigDecimal; @Service public class YourService { private final List<BigDecimal> someData; // 构造函数注入Resource和ObjectMapper,Spring会自动提供ObjectMapper实例 public YourService(@Value("classpath:mockedData.json") Resource mockedDataResource, ObjectMapper objectMapper) throws IOException { this.someData = objectMapper.readValue( mockedDataResource.getInputStream(), objectMapper.getTypeFactory().constructCollectionType(List.class, BigDecimal.class) ); } // 业务逻辑中直接使用someData }
方法二:使用@ConfigurationProperties(符合Spring配置规范)
如果需要加载更复杂的JSON配置,推荐用这种方式,通过自定义属性源工厂让Spring支持JSON格式的配置文件:
- 实现
JsonPropertySourceFactory,让Spring能解析JSON文件:
import org.springframework.core.env.MapPropertySource; import org.springframework.core.env.PropertySource; import org.springframework.core.io.support.EncodedResource; import org.springframework.core.io.support.PropertySourceFactory; import com.fasterxml.jackson.databind.ObjectMapper; import java.io.IOException; import java.util.Map; public class JsonPropertySourceFactory implements PropertySourceFactory { @Override public PropertySource<?> createPropertySource(String name, EncodedResource resource) throws IOException { ObjectMapper objectMapper = new ObjectMapper(); // 将JSON文件内容解析为Map,适配@ConfigurationProperties的读取逻辑 Map<String, Object> jsonMap = objectMapper.readValue(resource.getInputStream(), Map.class); return new MapPropertySource( name != null ? name : resource.getResource().getFilename(), jsonMap ); } }
- 创建配置类绑定JSON数据:
import org.springframework.boot.context.properties.ConfigurationProperties; import org.springframework.context.annotation.PropertySource; import org.springframework.stereotype.Component; import java.util.List; import java.math.BigDecimal; @Component @ConfigurationProperties(prefix = "mock") @PropertySource(value = "classpath:mockedData.json", factory = JsonPropertySourceFactory.class) public class MockDataConfig { private List<BigDecimal> data; // 必须提供getter和setter,Spring通过反射赋值 public List<BigDecimal> getData() { return data; } public void setData(List<BigDecimal> data) { this.data = data; } }
- 在服务类中注入配置类使用:
import org.springframework.stereotype.Service; @Service public class YourService { private final List<BigDecimal> someData; public YourService(MockDataConfig mockDataConfig) { this.someData = mockDataConfig.getData(); } // 业务逻辑中使用someData }
内容的提问来源于stack exchange,提问作者Czarek
相关产品推荐
相关产品推荐

