Spring Boot @PropertySource与yml文件一起使用

我们都知道,使用@PropertySource 的时候经常是类似于下面的用法。
 

@Component
@ConfigurationProperties(prefix = "netty-socket-io")
@PropertySource("classpath:server.properties")
@Getter
@Setter
public class ServerProperties {
    /**
     * socket端口
     */
    private Integer socketPort;

    /**
     * Ping消息间隔(毫秒)
     */
    private Integer pingInterval;

    /**
     * Ping消息超时时间(毫秒)
     */
    private Integer pingTimeout;

}

读取的都是properties文件,但是当你自己自定义了yml文件,该怎么用这种方法读取呢?难不成把yml换成properties文件?如果文件特别大呢?不过作为技术宅,有问题,还是应该解决一下问题。

Google上搜出了下面的文章,供参考。原文地址:https://mdeinum.github.io/2018-07-04-PropertySource-with-yaml-files/

By default the @PropertySource annotation isn’t usable with YAML files. This is also the standard answer given when asked on, for instance StackOverflow (even by me!).

But as of Spring 4.3 it’s possible to make it work. Spring 4.3 introduced the PropertySourceFactory interface. The PropertySourceFactory is a factory for a PropertySource. The default implementation used is the DefaultPropertySourceFactory, which creates ResourcePropertySource instances.

Writing a custom implementation requires implementing a single method, createPropertySource. The custom implementation needs to do 2 things:

  • Load the given resource into a java.util.Properties object
  • Create a PropertySource wrapping the loaded properties

To load a YAML file Spring provides the YamlPropertiesFactoryBean. This class will load 1 or more files and convert it into a java.util.Properties object. Spring provides a [PropertiesPropertySource] which wraps a java.util.Properties object. Finally the name of the PropertySource is either given or derived. The derived name is the resource description, as mentioned in the contract.

package biz.deinum.blog.yaml;

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

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 org.springframework.lang.Nullable;

public class YamlPropertySourceFactory implements PropertySourceFactory {

    @Override
    public PropertySource<?> createPropertySource(@Nullable String name, EncodedResource resource) throws IOException {
        Properties propertiesFromYaml = loadYamlIntoProperties(resource);
        String sourceName = name != null ? name : resource.getResource().getFilename();
        return new PropertiesPropertySource(sourceName, propertiesFromYaml);
    }

    private Properties loadYamlIntoProperties(EncodedResource resource) throws FileNotFoundException {
        try {
            YamlPropertiesFactoryBean factory = new YamlPropertiesFactoryBean();
            factory.setResources(resource.getResource());
            factory.afterPropertiesSet();
            return factory.getObject();
        } catch (IllegalStateException e) {
            // for ignoreResourceNotFound
            Throwable cause = e.getCause();
            if (cause instanceof FileNotFoundException)
                throw (FileNotFoundException) e.getCause();
            throw e;
        }
    }
}

NOTE: To load YAML it is required that SnakeYAML 1.18 or higher is on the classpath!

Next the YAML file, blog.yaml which we want to load:

foo:
  bar: baz

The @PropertySource annotation has a factory attribute. This is the attribute used to specify which PropertySourceFactory to use. Here we give it the value YamlPropertySourceFactory.class. The value attribute contains the name of the YAML resource to load.

package biz.deinum.blog.yaml;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.ConfigurableApplicationContext;
import org.springframework.context.annotation.PropertySource;
import org.springframework.core.env.ConfigurableEnvironment;

@SpringBootApplication
@PropertySource(factory = YamlPropertySourceFactory.class, value = "classpath:blog.yaml")
public class YamlPropertysourceApplication {

    public static void main(String[] args) {
        ConfigurableApplicationContext ctx =
                SpringApplication.run(YamlPropertysourceApplication.class, args);

        ConfigurableEnvironment env = ctx.getEnvironment();
        env.getPropertySources()
                .forEach(ps -> System.out.println(ps.getName() + " : " + ps.getClass()));

        System.out.println("Value of `foo.bar` = " + env.getProperty("foo.bar"));
    }
}

NOTE: Although this sample uses Spring Boot this isn’t required it works with plain Spring (version 4.3 or up) as well.

When running this application it will

  • Print the name and type of all available PropertySources
  • Get the value from foo.bar which comes from the blog.yaml file

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值