<导航

springboot读取配置文件总结

一、配置文件优先级加载机制

spring boot 启动会扫描以下位置的application.properties或者application.yml文件作为Spring boot的默认配置文件。

–file:./config/
–file:./
–classpath:/config/
–classpath:/

加载的优先级顺序是从上向下加载,并且所有的文件都会被加载,高优先级的内容会覆盖底优先级的内容,形成互补配置。

PS:不过需要注意的是在工程根路径下或者根路径的config下面的配置文件,在工程打包时候不会被打包进去(这也可能和项目级别有关系,Module级别与IDEA中Project级别的,待验证,未实操)。

我们可以从ConfigFileApplicationListener这类便可看出,其中DEFAULT_SEARCH_LOCATIONS属性设置了加载的目录:

private static final String DEFAULT_SEARCH_LOCATIONS = "classpath:/,classpath:/config/,file:./,file:./config/";

接着getSearchLocations方法中去逗号解析成Set,其中内部类Loader负责这一配置文件的加载过程,包括加载profile指定环境的配置,以application+’-’+name格式的拼接加载。


 下图所示:

 

以上是按照优先级从高到低(1-4)的顺序,所有位置的文件都会被加载,高优先级配置内容会覆盖低优先级配置内容。

PS:项目目录的config下面的application.yml和项目根目录下的application.yml扫描不进去,可能是因为你用的项目是Module级别的,你必须使用IDEA中Project级别的项目才能扫描到项目根路径下的东西(待验证,未实操)。

我们也可以通过配置spring.config.location来改变默认配置。

java -jar spring-boot-02-config-02-0.0.1-SNAPSHOT.jar --spring.config.location=D:/application.properties

另外也可以通过命令行参数进行配置:

  • 所有的配置都可以在命令行上进行指定;
  • 多个配置用空格分开; --配置项=值
java -jar spring-boot-02-config-02-0.0.1-SNAPSHOT.jar 
--server.port=8087 --server.context-path=/abc

以下优先级从高到底加载顺序:

  1.命令行参数

  2.来自java:comp/env的JNDI属性
  3.Java系统属性(System.getProperties())
  4.操作系统环境变量
  5.RandomValuePropertySource配置的random.*属性值
  6.jar包外部的application-{profile}.properties或application.yml(带spring.profile)配置文件
  7.jar包内部的application-{profile}.properties或application.yml(带spring.profile)配置文件
  8.jar包外部的application.properties或application.yml(不带spring.profile)配置文件
  9.jar包内部的application.properties或application.yml(不带spring.profile)配置文件

    Note:由jar包外向jar包内进行寻找,优先加载带profile的,再加载不带profile的。
  10.@Configuration注解类上的@PropertySource
  11.通过SpringApplication.setDefaultProperties指定的默认属性

参考官网地址官网图示如下:

二、properties配置优先级 > YAML配置优先级 

  SpringBoot使用一个以application命名的配置文件作为默认的全局配置文件。支持properties后缀结尾的配置文件或者以yml/yaml后缀结尾的YAML的文件配置。
以设置应用端口为例
properties文件示例(application.properties):

server.port=80

YAML文件示例(application.yml):

server:
  port: 80

yaml语法规范可以参照该篇文章:https://blog.csdn.net/it_faquir/article/details/79842885

两者同时存在情况
假如各配置文件都配置了不同的端口,那么SpringBoot会使用哪一个端口呢?带着疑问试验一下实例

在resources目录下创建两个配置文件,一个为application.yml配置文件,设置端口为8010,另一个为application.properties配置文件,设置端口为8020;
重启项目后运行结果:

结论:可见在同一目录下,properties配置优先级 > YAML配置优先级。//所以我们在jar包启动时带上properties写法的配置可以覆盖配置。

三、@PropertySource和@ImportResource

  通常情况下我们将配置配置在application开头的主配置文件中,这样随着项目的增大配置项的增多会使文件变得非常臃肿,其实SpringBoot早已考虑到了该问题,SpringBoot提供了**@PropertySource和@ImportResource**两个注解用于加载外部配置文件使用。

  • @PropertySource通常用于属性加载配置文件,注意@PropertySource注解不支持加载yaml文件,支持properties文件。
  • @ImportResource通常用于加载Spring的xml配置文件

@PropertySource使用

装配properties配置文件
在sources/config下创建一个yaml文件命名为user.properties内容与上方user的配置一样

@PropertySource(value = {"classpath:config/user.properties"})
@Component
@ConfigurationProperties(prefix = "user")
public class Login{
private String username;
private String password;
...
}

同时加载多个配置问题
细心的你,会发现@PropertySource注解中属性value为一个数组,如果同时加载多个配置文件,并且不同配置文件中对同一个属性设置了不同的值,那么Spring会识别哪一个呢?
带着疑问,我们可以通过控制变量法进行测试,具体过程再在赘述。

@PropertySource(value = {"classpath:config/user1.properties","classpath:config/user2.properties"})

结论:Spring加载顺序为从左到右顺序加载,后加载的会覆盖先加载的属性值。

配yaml配置文件
  如果你有强迫症,一定想加载yaml配置文件,那么可以通过PropertySourcesPlaceholderConfigurer类来加载yaml文件,将原来的user.properties改成user.yaml,Bean配置类中加入如下代码,Login配置类和一开始的方式一致。

@Bean
public static PropertySourcesPlaceholderConfigurer loadProperties() {
    PropertySourcesPlaceholderConfigurer configurer = new PropertySourcesPlaceholderConfigurer();
    YamlPropertiesFactoryBean yaml = new YamlPropertiesFactoryBean();
    //yaml.setResources(new FileSystemResource("classpath:config/user.yml"));//File路径引入
    yaml.setResources(new ClassPathResource("config/user.yml"));//class路径引入
    configurer.setProperties(yaml.getObject());
    return configurer;
}

运行一下,仍然可以能达到加载配置效果的。

@ImportResource使用

  SpringBoot提出零xml的配置,因此SpringBoot默认情况下是不会主动识别项目中Spring的xml配置文件。为了能够加载xml的配置文件,SpringBoot提供了@ImportResource注解该注解可以加载Spring的xml配置文件,通常加于启动类上。

@ImportResource(value = {"classpath:/beans.xml"})
@SpringBootApplication(scanBasePackages = {"team.seagull.client"})
public class DeployApplication {
    public static void main(String[] args) {
        SpringApplication.run(DeployApplication.class, args);
    }
}

四、一般配置文件方案参考

  我在自己的springboot项目中使用了多个配置文件,application.properties是主配置文件,放一些项目通用的配置,application-dev.properties 放的是平常开发的一些配置,比如说数据库的连接地址、帐号密码等,

application-prod.properties 放的是生产环境的一些配置,比如说数据库的连接地址、帐号密码等,

当然也可以再多一个application-test.properties ,放一些测试环境需要用到的参数。

可以通过在application.properties 中设置spring.profiles.active=prod或者dev来使用application-dev.properties或者application-prod.properties文件,当然test文件也是同理。

五、其他问题

idea使用*.properties文件出现中文乱码问题?
idea对*.properties默认编码为GBK,通常我们项目为UTF-8编码,这样程序在读取时就会出现乱码问题;
解决方法:idea 中 打开如下选项File->Sttings->Editor->FileEncodings

将GBK修改为UTF-8并勾选
Transparent native-to ascill conversion(在运行的时候转换成ascii码)

 

 

 

 参考文章:

 https://blog.csdn.net/J080624/article/details/80508606

 https://blog.csdn.net/it_faquir/article/details/80869578

 https://blog.csdn.net/huangyuehong914/article/details/80521917

posted @ 2019-09-25 13:01  字节悦动  阅读(6812)  评论(0编辑  收藏  举报