Spring Boot5种读取配置文件的方式

  • 一、@Value注解读取方式
  • 1.1 properties中文乱码
  • 1.2 yml的格式的空格注意
  • 1.3 当properties和yml有相同的配置的时候?
  • 1.4 当key不存在的时候?
  • 二、@ConfigurationProperties注解读取方式
  • 2.1 properties中文乱码问题
  • 2.2 key不存在问题
  • 三、@PropertySource+@Value注解读取方式
  • 3.1 中文乱码问题
  • 3.2 不支持yml文件
  • 四、@PropertySource+@ConfigurationProperties注解读取方式
  • 五、Environment读取方式
  • 总结


在Spring Boot中读取配置文件,常用的有5中方式,如果你还不清楚有哪四种方式,本文可以为你一一解答,如果你已经清楚了,那么本文会抛出一些新的问题引发你的思考。

你好! 这是你第一次使用 Markdown编辑器 所展示的欢迎页。如果你想学习如何使用Markdown编辑器, 可以仔细阅读这篇文章,了解一下Markdown的基本语法知识。

一、@Value注解读取方式

使用@Value的方式是最直接的方式,核心就是一个配置对应一个@Value的配置,我们看下示例代码:

在application(.yml |.properties)进行配置:

.properties文件:

author.name=悟纤
author.officialAccount=SpringBoot
author.introduce=悟纤是一只程序猿,有一个技术的公众号SpringBoot,目前已经输出了371篇文章

.yml文件:

author:
  name: 悟纤
  officialAccount: SpringBoot
  introduce: 悟纤是一只程序猿,有一个技术的公众号SpringBoot,目前已经输出了371篇文章

那么如何在代码中使用@Valu获取到这些配置呢?直接看代码:

import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;

/**
 *
 * 使用@Value注解读取方式
 *
 * @author 悟纤「公众号SpringBoot」
 * @date 2021-07-21
 * @slogan 大道至简 悟在天成
 */
@Component
public class AuthorConfig1 {
    @Value("${author.name}")
    private String name;

    @Value("${author.officialAccount}")
    private String officialAccount;

    @Value("${author.introduce}")
    private String introduce;

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getOfficialAccount() {
        return officialAccount;
    }

    public void setOfficialAccount(String officialAccount) {
        this.officialAccount = officialAccount;
    }

    public String getIntroduce() {
        return introduce;
    }

    public void setIntroduce(String introduce) {
        this.introduce = introduce;
    }

}

使用格式就是@Value("spring boot启动读取配置文件顺序 springboot怎么读取配置文件_spring boot{}这个包裹起来,如果少了这个,变成这样的代码:@Value(“author.name”),那么就是原样输出了,name的值就是author.name了。

1.1 properties中文乱码

我们会发现当使用properites出现中文乱码的问题了,哎,看着就很头大:

用@Value注解读取application.properties文件时,编码默认是ISO-8859-1,所以直接配置中文一定会乱码。注意,配置文件是springboot默认的配置文件application.properties或application-{active}.properties。

为什么是这样子的呢?我们下文通过源码进行分析,以及如何破局?

1.2 yml的格式的空格注意

对于yml的格式是很严格的,有点小小的不符合规则就无法解析了。比如name:后面是有一个空格的,如果直接挨着value值就不对了。

spring boot启动读取配置文件顺序 springboot怎么读取配置文件_中文乱码_02


对于反例,格式有误的情况下,key的颜色都显示不对的,那么应用启动的话,也会报错了:

spring boot启动读取配置文件顺序 springboot怎么读取配置文件_中文乱码_03

提示的位置也是怪怪的,不应该是line 2的问题吗?好吧,这个管不了,是line 2的问题导致了line 3也解析不出来了。只需要在“悟纤“的前面加一个空格即可修复此异常。

1.3 当properties和yml有相同的配置的时候?

当properties和yml有相同的配置的时候,由于加载顺序是先yml文件再properties文件,但后面加载的会覆盖前面加载的,也就是说最终结果以properties文件的配置信息为主。

1.4 当key不存在的时候?

当使用@Value指定了一个不存在的key的时候,是会报错的:

Injection of autowireddependencies failed; nested exception is java.lang.IllegalArgumentException:
Could not resolve placeholder 'author.introduce' in value"${author.introduce}"

这个报错信息还是很明显的,很容易解决问题。

二、@ConfigurationProperties注解读取方式

对于配置文件一样,我们看下java代码:

package com.kfit.springboothellosts.config;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;

/**
 *
 * 使用@ConfigurationProperties注解读取方式
 *
 * @author 悟纤「公众号SpringBoot」
 * @date 2021-07-21
 * @slogan 大道至简 悟在天成
 */
@Component
@ConfigurationProperties(prefix = "author")
public class AuthorConfig2 {

    private String name;

    private String officialAccount;

    private String introduce;

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getOfficialAccount() {
        return officialAccount;
    }

    public void setOfficialAccount(String officialAccount) {
        this.officialAccount = officialAccount;
    }

    public String getIntroduce() {
        return introduce;
    }

    public void setIntroduce(String introduce) {
        this.introduce = introduce;
    }
}

使用@ConfigurationProperties如果不识别,需要添加依赖包:

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-configuration-processor</artifactId>
</dependency>

2.1 properties中文乱码问题

这种方式还是有中文乱码问题。

2.2 key不存在问题

对于key不存在的问题,这种读取方式是不会报错的,当然可以进行配置:
@ConfigurationProperties(prefix = "author",ignoreUnknownFields = false)

三、@PropertySource+@Value注解读取方式

PropertySource需要指定一个properties的配置文件,我们准备一个db.properties的文件:

db.username=root
db.password=root-中文

使用@ProperrtySource+@Value进行使用配置信息:

package com.kfit.springboothellosts.config;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.PropertySource;
import org.springframework.stereotype.Component;


package com.kfit.springboothellosts.config;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.PropertySource;
import org.springframework.stereotype.Component;

/**
 *
 * 使用@ConfigurationProperties注解读取方式
 *
 * @author 悟纤「公众号SpringBoot」
 * @date 2021-07-21
 * @slogan 大道至简 悟在天成
 */
@Component
@PropertySource(value=" classpath:config/db.properties")
public class AuthorConfig3 {
    @Value("${db.username}")
    private String username;

    @Value("${db.password}")
    private String password;

    public String getUsername() {
        return username;
    }

    public void setUsername(String username) {
        this.username = username;
    }

    public String getPassword() {
        return password;
    }

    public void setPassword(String password) {
        this.password = password;
    }

}

3.1 中文乱码问题

对于这个中文乱码问题是可以解决的,只需要添加一个属性指定编码即可:

@PropertySource(value="config/db.properties",encoding = "utf-8")

3.2 不支持yml文件

@PropertySource不支持yml文件读取。

四、@PropertySource+@ConfigurationProperties注解读取方式

配置文件和第三种方式是一样的一样的,这是在java代码层面稍微不同。

package com.kfit.springboothellosts.config;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.PropertySource;
import org.springframework.stereotype.Component;

/**
 *
 * 使用@ConfigurationProperties注解读取方式
 *
 * @author 悟纤「公众号SpringBoot」
 * @date 2021-07-21
 * @slogan 大道至简 悟在天成
 */
@Component
@PropertySource(value="classpath:config/db.properties",encoding = "utf-8")
@ConfigurationProperties(prefix = "db")
public class AuthorConfig4 {
    private String username;

    private String password;

    public String getUsername() {
        return username;
    }

    public void setUsername(String username) {
        this.username = username;
    }

    public String getPassword() {
        return password;
    }

    public void setPassword(String password) {
        this.password = password;
    }

   
}

五、Environment读取方式

以上所有加载出来的配置都可以通过Environment注入获取到。

@Autowired
private Environment environment;

String authName = environment.getProperty("author.name");
String dbUsername = environment.getProperty("db.username");

总结

在这这一节中呐,和大家一起学习了5种读取配置的方式,我们来回顾一下:

(1)@Value:使用@Value(“${key}”)的方式,支持.properties和.yml格式。

(2)@ConfigurationProperties:核心属性是prefix,指定属性的前缀,这样在java类的属性上就不需要注解。

(3)@PropertySource+@Value:可以自定义properties的文件名称。

(4)@PropertySource+@ ConfigurationProperties:可以自定义properties的文件名称和指定属性的前缀。

(5)Environment:引入环境对象,通过方法getProperty指定key进行获取。