欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

SpringBoot配置加载,各配置文件优先级对比方式

程序员文章站 2022-03-25 14:51:41
目录1.springboot配置文件@propertysource使用@importresource使用1.springboot配置文件springboot使用一个以application命名的配置文...

1.springboot配置文件

springboot使用一个以application命名的配置文件作为默认的全局配置文件。支持properties后缀结尾的配置文件或者以yml/yaml后缀结尾的yaml的文件配置。

以设置应用端口为例

properties文件示例(application.properties):

server.port=80

yaml文件示例(application.yml):

server:
  port: 80

yaml语法规范这里不多说

两者同时存在情况

假如各配置文件都配置了不同的端口,那么springboot会使用哪一个端口呢?带着疑问试验一下实例

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

SpringBoot配置加载,各配置文件优先级对比方式

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

2.配置文件目录

springboot配置文件可以放置在多种路径下,不同路径下的配置优先级有所不同。可放置目录(优先级从高到低)

  • file:./config/ (当前项目路径config目录下);
  • file:./ (当前项目路径下);
  • classpath:/config/ (类路径config目录下);
  • classpath:/ (类路径config下).

优先级由高到底,高优先级的配置会覆盖低优先级的配置

springboot会从这四个位置全部加载配置文件并互补配置

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

private static final string default_search_locations = "classpath:/,classpath:/config/,file:./,file:./config/";

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

多种目录配置同时存在情况

接下来还是以端口配置为例

  • 在resources/目录下配置文件设置端口为8888;
  • 在resources/config目录下配置文件设置端口为9999;
  • 在项目路径下配置文件设置端口为6666;
  • 在项目路径config目录下配置文件设置端口为7777;

SpringBoot配置加载,各配置文件优先级对比方式

最终运行结果:

tomcat started on port(s): 7777 (http) with context path '/beedo'

started beedoapplication in 4.544 seconds (jvm running for 5.335)

通过控制变量法得以论证

其优先级由高到底,高优先级的配置会覆盖低优先级的配置

3.自定义配置属性

springboot提供了许多的配置,但通常情况我们需要自定义自己的配置应用自己的系统中,如你需要配置一个默认的用户名密码做为系统的登录用。

首先创建一个实体类,作为配置注入用,并使用**@configurationproperties注解进行批量注入, 也可以使用spring底层注解

@value("${user.username}")**的方式一个一个注入达到同意的效果

@component
@configurationproperties(prefix = "user")
public class login{
    private string username;
    private string password;
    ...
}

或者@value写法

@component
public class login{    
    private string username;
    private string password;
    ...
}

配置yaml文件

user:
    username: admin
    password: 123

或者properties文件

login.username=admin
login.password=123

编写一个junit测试用例,看看配置的值是否正常注入:

@runwith(springrunner.class)
@springboottest
public class deployapplicationtests {
    @autowired
    private login login;
    @test
    public void contextloads() {
        system.out.println(login);
    }
}

从输出结果上看,值已正常注入

login{username=‘admin', password=‘123'}

比较项 @configurationproperties @value
全量注入 支持
松散绑定(relaxed binding) 支持
spel 支持
jsr303 支持 不支持

**松散绑定:**驼峰命名(username)、横干拼接(user-name)、下划线(user_name)之间可以互相识别绑定称为做松散绑定 **jsr303:**通过@email,@nullable,@digits 等等注解进行邮箱、判空、数字格式等等数据的校验,更多相关内容请参考ibm的中文文档:https://www.ibm.com/developerworks/cn/java/j-lo-jsr303/index.html @configurationproperties通常用于将配置全量注入某个类中; @value通常用于注入某一些特定配置值中;

自定义配置提示

在编写配置时,你会发现自定义配置没有提示,让你在使用自定义配置时变的很麻烦,其实springboot早已为我们准备好了提示的需要,只需要用引入相关依赖即可有提示。

在没有加入依赖时idea会有如下提示:

SpringBoot配置加载,各配置文件优先级对比方式

添加依赖,该idea提示便消失,编写自定义配置时也有相应提示:

<dependency>
    <groupid>org.springframework.boot</groupid>
    <artifactid>spring-boot-configuration-processor</artifactid>
    <optional>true</optional>
</dependency>

需要运行一下

4.指定配置文件

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

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

@propertysource使用

装配properties配置文件

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

SpringBoot配置加载,各配置文件优先级对比方式

login类可如下写法

@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);
    }
}

其他问题

idea使用*.properties文件出现中文乱码问题?

idea对*.properties默认编码为gbk,通常我们项目为utf-8编码,这样程序在读取时就会出现乱码问题;

解决方法:

idea 中 打开如下选项file->sttings->editor->fileencodings

SpringBoot配置加载,各配置文件优先级对比方式

将gbk修改为utf-8并勾选

transparent native-to ascill conversion(在运行的时候转换成ascii码)

以上为个人经验,希望能给大家一个参考,也希望大家多多支持。