从 json 文件加载 spring-boot 属性

Posted

技术标签:

【中文标题】从 json 文件加载 spring-boot 属性【英文标题】:Load spring-boot properties from json file 【发布时间】:2017-11-17 18:00:54 【问题描述】:

是否可以从 .json 文件而不是 .yaml 或 .properties 文件加载 spring-boot 配置?从查看文档来看,这不是开箱即用的支持 - 我想知道这是否可能,如果可以,如何去做?

【问题讨论】:

为什么要从 json 加载配置? 它是一个框架,它是 spring-boot 的包装器。框架的用户更喜欢使用 json 作为配置文件。 在 spring boot 加载 yaml 之前将 json 转换为 yaml。 查看这篇精彩的博文。 baeldung.com/spring-boot-json-properties 【参考方案1】:

如上所述 in docs 和 on GitHub

YAML 是 JSON 的超集

所以你可以在你的 Spring Boot 项目中创建以下类:

public class JsonPropertySourceLoader extends YamlPropertySourceLoader 
    @Override
    public String[] getFileExtensions() 
        return new String[]"json";
    

然后创建一个文件:

/src/main/resources/META-INF/spring.factories 内容如下:

org.springframework.boot.env.PropertySourceLoader=\
io.myapp.JsonPropertySourceLoader

您的 Spring 应用程序已准备好从 application.json 加载 JSON 配置。优先级是:.properties -> .yaml -> .json

如果您有多个应用程序,您可以使用共享的 PropertySourceLoaderspring.factories 文件创建一个 jar,以便将其包含到您需要的任何项目中。

【讨论】:

【参考方案2】:

可以在命令行中使用环境变量提供 SPRING_APPLICATION_JSON 属性。例如,您可以在 UN*X shell 中使用以下行:

$ SPRING_APPLICATION_JSON='"acme":"name":"test"' java -jar myapp.jar

在前面的示例中,您最终会在 Spring 环境中使用 acme.name=test。您还可以在 System 属性中将 JSON 作为 spring.application.json 提供,如下例所示:

$ java -Dspring.application.json='"name":"test"' -jar myapp.jar

您还可以使用命令行参数提供 JSON,如下例所示:

$ java -jar myapp.jar --spring.application.json='"name":"test"'

您还可以将 JSON 作为 JNDI 变量提供,如下所示:

java:comp/env/spring.application.json.

参考文档:https://docs.spring.io/spring-boot/docs/current/reference/html/boot-features-external-config.html

【讨论】:

【参考方案3】:

spring boot方式:

@EnableAutoConfiguration
@Configuration
@PropertySource(value =  "classpath:/properties/config.default.json" , factory=SpringBootTest.JsonLoader.class )
public class SpringBootTest extends SpringBootServletInitializer 

    @Bean
    public Object test(Environment e) 
        System.out.println(e.getProperty("test"));
        return new Object();
    


    public static void main(String[] args) 
        SpringApplication.run(SpringBootTest.class);
    

    public static class JsonLoader implements PropertySourceFactory 

        @Override
        public org.springframework.core.env.PropertySource<?> createPropertySource(String name,
                EncodedResource resource) throws IOException 
            Map readValue = new ObjectMapper().readValue(resource.getInputStream(), Map.class);
            return new MapPropertySource("json-source", readValue);
        

    

定义您自己的PropertySourceFactory 并通过@PropertySource 注释将其挂钩。阅读资源,设置属性,在任何地方使用它们。

唯一的问题是,如何翻译嵌套属性。 Spring 的方法(顺便说一下,您也可以将 Json 定义为属性的变量,请参阅:https://docs.spring.io/spring-boot/docs/current/reference/html/boot-features-external-config.html) 就是这样翻译嵌套属性:

"test":  "test2" : "x"  

变成:

test.test2.x

希望对你有帮助,

阿图尔

【讨论】:

【参考方案4】:

两步

public String asYaml(String jsonString) throws JsonProcessingException, IOException 
    // parse JSON
    JsonNode jsonNodeTree = new ObjectMapper().readTree(jsonString);
    // save it as YAML
    String jsonAsYaml = new YAMLMapper().writeValueAsString(jsonNodeTree);
    return jsonAsYaml;

来自the post

public class YamlFileApplicationContextInitializer implements ApplicationContextInitializer<ConfigurableApplicationContext> 
  @Override
  public void initialize(ConfigurableApplicationContext applicationContext) 
    try 
        Resource resource = applicationContext.getResource("classpath:file.yml");
        YamlPropertySourceLoader sourceLoader = new YamlPropertySourceLoader();
        PropertySource<?> yamlTestProperties = yamlTestProperties = sourceLoader.load("yamlTestProperties", resource, null);
        applicationContext.getEnvironment().getPropertySources().addFirst(yamlTestProperties);
     catch (IOException e) 
        throw new RuntimeException(e);
    
  

来自the post

所以你可以将两者结合起来。将您的 json 作为资源加载并转换为 yaml,然后将所有找到的属性添加到 Environment

【讨论】:

以上是关于从 json 文件加载 spring-boot 属性的主要内容,如果未能解决你的问题,请参考以下文章

spring-boot 加载本地静态资源文件路径配置

Spring-Boot 多模块项目加载属性文件

spring-boot学习五:Spring boot配置文件的加载位置

使用 Spring-Boot 2.1 从 .yml 读取对象列表 [重复]

在Spring-boot中,为@Value注解添加从数据库读取properties支持

Spring-Boot 2 AspectJ 加载时间编织