Spring Boot怎么读取自定义配置文件

发布时间:2021-05-31 10:21:14 作者:小新
来源:亿速云 阅读:325

这篇文章给大家分享的是有关Spring Boot怎么读取自定义配置文件的内容。小编觉得挺实用的,因此分享给大家做个参考,一起跟随小编过来看看吧。

@Value

首先,会想到使用@Value注解,该注解只能去解析yaml文件中的简单类型,并绑定到对象属性中去。

felord:
  phone: 182******32
  def:
    name: 码农小胖哥
    blog: felord.cn
    we-chat: MSW_623
  dev:
    name: 码农小胖哥
    blog: felord.cn
    we-chat: MSW_623
  type: JUEJIN

对于上面的yaml配置,如果我们使用@Value注解的话,冒号后面直接有值的key才能正确注入对应的值。例如felord.phone我们可以通过@Value获取,但是felord.def不行,因为felord.def后面没有直接的值,它还有下一级选项。另外@Value不支持yaml松散绑定语法,也就是说felord.def.weChat获取不到felord.def.we-chat的值。

@Value是通过使用Spring的SpEL表达式来获取对应的值的:

// 获取 yaml 中 felord.phone的值 并提供默认值 UNKNOWN
@Value("${felord.phone:UNKNOWN}")
 private String phone;

@Value的使用场景是只需要获取配置文件中的某项值的情况下,如果我们需要将一个系列的值进行绑定注入就建议使用复杂对象的形式进行注入了。

@ConfigurationProperties

@ConfigurationProperties注解提供了我们将多个配置选项注入复杂对象的能力。它要求我们指定配置的共同前缀。比如我们要绑定felord.def下的所有配置项:

package cn.felord.yaml.properties;
 
import lombok.Data;
import org.springframework.boot.context.properties.ConfigurationProperties;
 
import static cn.felord.yaml.properties.FelordDefProperties.PREFIX;
 
/**
 * @author felord.cn
 */
@Data
@ConfigurationProperties(PREFIX)
public class FelordDefProperties {
    static final String PREFIX = "felord.def";
    private String name;
    private String blog;
    private String weChat;
}

我们注意到我们可以使用weChat接收we-chat的值,因为这种形式支持从驼峰camel-case到短横分隔命名kebab-case的自动转换。

如果我们使用@ConfigurationProperties的话建议配置类命名后缀为Properties,比如Redis的后缀就是RedisProperties,RabbitMQ的为RabbitProperties。

另外我们如果想进行嵌套的话可以借助于@NestedConfigurationProperty注解实现。也可以借助于内部类。这里用内部类实现将开头yaml中所有的属性进行注入:

package cn.felord.yaml.properties;
 
import lombok.Data;
import org.springframework.boot.context.properties.ConfigurationProperties;
 
import static cn.felord.yaml.properties.FelordProperties.PREFIX;
 
 
/**
 * 内部类和枚举配置.
 *
 * @author felord.cn
 */
@Data
@ConfigurationProperties(PREFIX)
public class FelordProperties {
 
    static final String PREFIX = "felord";
    private Def def;
    private Dev dev;
    private Type type;
 
    @Data
    public static class Def {
        private String name;
        private String blog;
        private String weChat;
    }
 
    @Data
    public static class Dev {
        private String name;
        private String blog;
        private String weChat;
    }
 
    public enum Type {
        JUEJIN,
        SF,
        OSC,
        CSDN
    }
}

单独使用@ConfigurationProperties的话依然无法直接使用配置对象FelordDefProperties,因为它并没有被注册为Spring Bean。我们可以通过两种方式来使得它生效。

显式注入 Spring IoC

你可以使用@Component、@Configuration等注解将FelordDefProperties注入Spring IoC使之生效。

package cn.felord.yaml.properties;
 
import lombok.Data;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;
 
import static cn.felord.yaml.properties.FelordDefProperties.PREFIX;
 
/**
 * 显式注入Spring IoC
 * @author felord.cn
 */
@Data
@Component
@ConfigurationProperties(PREFIX)
public class FelordDefProperties {
    static final String PREFIX = "felord.def";
    private String name;
    private String blog;
    private String weChat;
}

@EnableConfigurationProperties

我们还可以使用注解@EnableConfigurationProperties进行注册,这样就不需要显式声明配置类为Spring Bean了。

package cn.felord.yaml.configuration;
 
import cn.felord.yaml.properties.FelordDevProperties;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.Configuration;
 
/**
 * 使用 {@link EnableConfigurationProperties} 注册 {@link FelordDevProperties}使之生效
 * @author felord.cn
 */
@EnableConfigurationProperties({FelordDevProperties.class})
@Configuration
public class FelordConfiguration {
}

该注解需要显式的注册对应的配置类。

@ConfigurationPropertiesScan

在Spring Boot 2.2.0.RELEASE中提供了一个扫描注解@ConfigurationPropertiesScan。它可以扫描特定包下所有的被@ConfigurationProperties标记的配置类,并将它们进行IoC注入。

package cn.felord.yaml;
 
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.context.properties.ConfigurationPropertiesScan;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
 
/**
 * {@link ConfigurationPropertiesScan} 同 {@link EnableConfigurationProperties} 二选一
 *
 * @see cn.felord.yaml.configuration.FelordConfiguration
 * @author felord.cn
 */
@ConfigurationPropertiesScan
@SpringBootApplication
public class SpringBootYamlApplication {
 
    public static void main(String[] args) {
        SpringApplication.run(SpringBootYamlApplication.class, args);
    }
 
}

这非常适合自动注入和批量注入配置类的场景,但是有版本限制,必须在2.2.0及以上。

@PropertySource注解

@PropertySource可以用来加载指定的配置文件,默认它只能加载*.properties文件,不能加载诸如yaml等文件。

@PropertySource相关属性介绍

@Data
@AllArgsConstructor
@NoArgsConstructor
@Builder
@Configuration
@PropertySource(value = {"classpath:common.properties"},ignoreResourceNotFound=false,encoding="UTF-8")
@ConfigurationProperties(prefix = "author")
public class Author {
    private String name;
    private String job;
    private String sex;
}

有小伙伴也许发现示例上的@ConfigurationProperties注解了。当我们使用@Value需要注入的值较多时,代码就会显得冗余。我们可以使用@ConfigurationProperties 中的 prefix 用来指明我们配置文件中需要注入信息的前缀

前边提到了用@PropertySource只能加载*.properties文件,但如果我们项目的配置文件不是*.properties这种类型,而是其他类型,诸如yaml,此时我们可以通过实现PropertySourceFactory接口,重写createPropertySource方法,就能实现用@PropertySource也能加载yaml等类型文件。

public class YamlPropertySourceFactory implements PropertySourceFactory {
    @Override
    public PropertySource<?> createPropertySource(String sourceName, EncodedResource resource) throws IOException {
        Properties propertiesFromYaml = loadYaml(resource);
        if(StringUtils.isBlank(sourceName)){
            sourceName =  resource.getResource().getFilename();;
        }

        return new PropertiesPropertySource(sourceName, propertiesFromYaml);
    }
    private Properties loadYaml(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;
        }
    }
}
@Data
@AllArgsConstructor
@NoArgsConstructor
@Builder
@Configuration
@PropertySource(factory = YamlPropertySourceFactory.class,value = {"classpath:user.yml"},ignoreResourceNotFound=false,encoding="UTF-8")
@ConfigurationProperties(prefix = "user")
public class User {
    private String username;

    private String password;
}

使用EnvironmentPostProcessor加载自定义配置文件

1、实现EnvironmentPostProcessor接口,重写postProcessEnvironment方法

@Slf4j
public class CustomEnvironmentPostProcessor implements EnvironmentPostProcessor {
    @Override
    public void postProcessEnvironment(ConfigurableEnvironment environment, SpringApplication application) {

        Properties properties = new Properties();

        try {
            properties.load(new InputStreamReader(CustomEnvironmentPostProcessor.class.getClassLoader().getResourceAsStream("custom.properties"),"UTF-8"));

            PropertiesPropertySource propertiesPropertySource = new PropertiesPropertySource("custom",properties);
            environment.getPropertySources().addLast(propertiesPropertySource);
        } catch (IOException e) {
          log.error(e.getMessage(),e);
        }

    }
}

2、在META-INF下创建spring.factories

spring.factories文件内容如下:
org.springframework.boot.env.EnvironmentPostProcessor=com.github.lybgeek.env.CustomEnvironmentPostProcessor

1、2步骤实现完后,就可以在代码中直接用@Value的方式获取自定义配置文件内容了

读取的自定义配置文件内容的实现方法有多种多样,除了上面的方法,还可以在以-jar方式启动时,执行形如下命令

java -jar project.jar --spring.config.location=classpath:/config/custom.yml

也能实现。还可以干脆自定义配置文件都以application-*为前缀,比如application-custom,然后在application.properties,使用spring.profiles.include=custom或者spring.profiles.active=custom也可以实现

感谢各位的阅读!关于“Spring Boot怎么读取自定义配置文件”这篇文章就分享到这里了,希望以上内容可以对大家有一定的帮助,让大家可以学到更多知识,如果觉得文章不错,可以把它分享出去让更多的人看到吧!

推荐阅读:
  1. Spring boot注解分析
  2. Spring Boot 2.0 配置图文教程

免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。

spring boot

上一篇:nexus怎么安装

下一篇:Java中包装类Integer的使用方法

相关阅读

您好,登录后才能下订单哦!

密码登录
登录注册
其他方式登录
点击 登录注册 即表示同意《亿速云用户服务条款》