如何使用YamlPropertiesFactoryBean使用Spring Framework 4.1加载YAML文件?

ktu*_*nho 35 java spring yaml properties-file

我有一个当前使用*.properties文件的spring应用程序,我希望使用YAML文件.

我发现类YamlPropertiesFactoryBean似乎能够做我需要的.

我的问题是我不确定如何在我的Spring应用程序(使用基于注释的配置)中使用此类.看来我应该使用 setBeanFactory方法在PropertySourcesPlaceholderConfigurer中配置它.

以前我使用@PropertySource加载属性文件,如下所示:

@Configuration
@PropertySource("classpath:/default.properties")
public class PropertiesConfig {

    @Bean
    public static PropertySourcesPlaceholderConfigurer placeholderConfigurer() {
        return new PropertySourcesPlaceholderConfigurer();
    }
}
Run Code Online (Sandbox Code Playgroud)

如何在PropertySourcesPlaceholderConfigurer中启用YamlPropertiesFactoryBean以便我可以直接加载YAML文件?还是有另一种方法吗?

谢谢.

我的应用程序使用基于注释的配置,我使用的是Spring Framework 4.1.4.我找到了一些信息,但它始终指向Spring Boot,就像一样.

tur*_*own 70

使用XML配置我一直在使用这个结构:

<context:annotation-config/>

<bean id="yamlProperties" class="org.springframework.beans.factory.config.YamlPropertiesFactoryBean">
    <property name="resources" value="classpath:test.yml"/>
</bean>

<context:property-placeholder properties-ref="yamlProperties"/>
Run Code Online (Sandbox Code Playgroud)

当然,您必须对运行时类路径具有snakeyaml依赖性.

我更喜欢使用java配置的XML配置,但我认为它不应该很难转换它.

编辑:
java配置为完整性的缘故

@Bean
public static PropertySourcesPlaceholderConfigurer properties() {
  PropertySourcesPlaceholderConfigurer propertySourcesPlaceholderConfigurer = new PropertySourcesPlaceholderConfigurer();
  YamlPropertiesFactoryBean yaml = new YamlPropertiesFactoryBean();
  yaml.setResources(new ClassPathResource("default.yml"));
  propertySourcesPlaceholderConfigurer.setProperties(yaml.getObject());
  return propertySourcesPlaceholderConfigurer;
}
Run Code Online (Sandbox Code Playgroud)

  • 感谢您的回答.我现在如何将`default.yml`中的值注入到我的Java类中?因此,如果我的yml包含一个属性`value:60`,我可以在我的代码中简单地执行此操作:`@Value("$ {value}")private String value;`? (4认同)
  • 您可以像使用常规.properties文件一样使用从yaml文件加载的属性.因此,在任何Spring托管类中,您确实可以使用`@Value("$ {value}")私有字符串值`的确切示例,并且它将被注入. (2认同)
  • 如何加载多个文件? (2认同)

ayu*_*huk 5

要在 Spring 中读取 .yml 文件,您可以使用下一种方法。

例如,您有这个 .yml 文件:

section1:
  key1: "value1"
  key2: "value2"
section2:
  key1: "value1"
  key2: "value2"
Run Code Online (Sandbox Code Playgroud)

然后定义2个Java POJO:

@Configuration
@EnableConfigurationProperties
@ConfigurationProperties(prefix = "section1")
public class MyCustomSection1 {
    private String key1;
    private String key2;

    // define setters and getters.
}

@Configuration
@EnableConfigurationProperties
@ConfigurationProperties(prefix = "section2")
public class MyCustomSection1 {
    private String key1;
    private String key2;

    // define setters and getters.
}
Run Code Online (Sandbox Code Playgroud)

现在您可以在组件中自动装配这些 bean。例如:

@Component
public class MyPropertiesAggregator {

    @Autowired
    private MyCustomSection1 section;
}
Run Code Online (Sandbox Code Playgroud)

如果您使用 Spring Boot,所有内容都会被自动扫描和实例化:

@SpringBootApplication
public class MainBootApplication {
     public static void main(String[] args) {
        new SpringApplicationBuilder()
            .sources(MainBootApplication.class)
            .bannerMode(OFF)
            .run(args);
     }
}
Run Code Online (Sandbox Code Playgroud)

如果您使用 JUnit,则有一个用于加载 YAML 文件的基本测试设置:

@RunWith(SpringJUnit4ClassRunner.class)
@SpringApplicationConfiguration(MainBootApplication.class)
public class MyJUnitTests {
    ...
}
Run Code Online (Sandbox Code Playgroud)

如果您使用 TestNG,则有一个测试配置示例:

@SpringApplicationConfiguration(MainBootApplication.class)
public abstract class BaseITTest extends AbstractTestNGSpringContextTests {
    ....
}
Run Code Online (Sandbox Code Playgroud)

  • 抱歉,您的示例与 _Spring Boot_ 有关。问题是关于_plain_ Spring Framework 4.1 (18认同)

Mah*_*yeb 5

`

package com.yaml.yamlsample;

import com.yaml.yamlsample.config.factory.YamlPropertySourceFactory;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.CommandLineRunner;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.PropertySource;

@SpringBootApplication
@PropertySource(value = "classpath:My-Yaml-Example-File.yml", factory = YamlPropertySourceFactory.class)
public class YamlSampleApplication implements CommandLineRunner {

    public static void main(String[] args) {
        SpringApplication.run(YamlSampleApplication.class, args);
    }

    @Value("${person.firstName}")
    private String firstName;
    @Override
    public void run(String... args) throws Exception {
        System.out.println("first Name              :" + firstName);
    }
}


package com.yaml.yamlsample.config.factory;
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 {
         if (resource == null) {
            return super.createPropertySource(name, resource);
        }
        List<PropertySource<?>> propertySourceList = new YamlPropertySourceLoader().load(resource.getResource().getFilename(), resource.getResource());
        if (!propertySourceList.isEmpty()) {
            return propertySourceList.iterator().next();
        }
        return super.createPropertySource(name, resource);
    }
}
Run Code Online (Sandbox Code Playgroud)

My-Yaml-Example-File.yml

person:
  firstName: Mahmoud
  middleName:Ahmed
Run Code Online (Sandbox Code Playgroud)

参考我在 github spring-boot-yaml-sample 上的例子所以你可以加载 yaml 文件并使用 @Value() 注入值