spring boot 从 yml 文件读取属性

war*_*107 7 spring-boot

我有一个 Spring Boot 应用程序,必须从 yaml 文件读取属性。

代码:

@Component
@PropertySource("classpath:application.yml")
public class ResourceProvider {

    @Autowired
    private Environment env;

    public String getValue(String key) {
        return env.getProperty("app.max.size");
    }
}
Run Code Online (Sandbox Code Playgroud)

yaml 文件

app:
  max:
    size: 10
Run Code Online (Sandbox Code Playgroud)

当我尝试这个时,它不起作用。我得到的值为app.max.size空。因为size我得到的值为 10。

当我使用 application.properties 时。我能够得到想要的结果。我做错了什么吗?

应用程序属性

 app.max.size=10
Run Code Online (Sandbox Code Playgroud)

Sac*_*lla 11

由于您使用的是application.yml文件,因此不需要手动将文件加载到上下文,因为它是spring应用程序的默认配置文件。您可以简单地在@Component装饰类中使用它们,如下所示;

@Value("${app.max.size}")
private int size;
Run Code Online (Sandbox Code Playgroud)

如果您正在加载自定义YAML文件,那么这在 Spring 中是一个大问题。使用@PropertySource你不能简单地加载YAML文件。这是可能的,但几乎不需要做任何工作。首先,您需要一个自定义属性源工厂。在您的情况下,自定义 YAML 属性源工厂。

import org.springframework.beans.factory.config.YamlPropertiesFactoryBean;
import org.springframework.core.env.PropertiesPropertySource;
import org.springframework.core.env.PropertySource;
import org.springframework.core.io.support.EncodedResource;
import org.springframework.core.io.support.PropertySourceFactory;

import java.io.FileNotFoundException;
import java.io.IOException;
import java.util.Objects;
import java.util.Properties;

public class YamlPropertySourceFactory implements PropertySourceFactory {

    /**
     * Create a {@link PropertySource} that wraps the given resource.
     *
     * @param name     the name of the property source
     * @param resource the resource (potentially encoded) to wrap
     * @return the new {@link PropertySource} (never {@code null})
     * @throws IOException if resource resolution failed
     */
    @Override
    public PropertySource<?> createPropertySource(String name, EncodedResource resource)
            throws IOException {
        Properties properties = load(resource);
        return new PropertiesPropertySource(name != null ? name :
                Objects.requireNonNull(resource.getResource().getFilename(), "Some error message"),
                properties);
    }

    /**
     * Load properties from the YAML file.
     *
     * @param resource Instance of {@link EncodedResource}
     * @return instance of properties
     */
    private Properties load(EncodedResource resource) throws FileNotFoundException {
        try {
            YamlPropertiesFactoryBean factory = new YamlPropertiesFactoryBean();
            factory.setResources(resource.getResource());
            factory.afterPropertiesSet();

            return factory.getObject();
        } catch (IllegalStateException ex) {
            /*
             * Ignore resource not found.
             */
            Throwable cause = ex.getCause();
            if (cause instanceof FileNotFoundException) throw (FileNotFoundException) cause;
            throw ex;
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

而且,每当您使用它时,您都需要告诉@PropertySource注释使用此工厂而不是默认工厂,如下所示;

@Component
@PropertySource(value = "classpath:config-prop.yml", factory = YamlPropertySourceFactory.class) // Note the file name with the extension unlike a property file. Also, it's not the `application.yml` file.
public class ResourceProvider { 

    @Value("${app.max.size}")
    private int size;
}
Run Code Online (Sandbox Code Playgroud)

您可以使用上面代码片段的变量中显示的属性size

尽管。如果您使用 YAML 数组声明来获取属性,那么即使您使用这种方式,也没什么奇怪的。