SpringBoot源码分析(4)--Environment(下)/配置文件加载原理

这篇具有很好参考价值的文章主要介绍了SpringBoot源码分析(4)--Environment(下)/配置文件加载原理。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

SpringBoot源码分析

  1. SpringBoot源码分析(1)–@SpringBootApplication注解使用和原理/SpringBoot的自动配置原理详解
  2. SpringBoot源码分析(2)–SpringBoot启动源码(万字图文源码debug讲解springboot启动原理)
  3. SpringBoot源码分析(3)–Environment简介/prepareEnvironment准备环境(万字图文源码debug分析)

一、前言

上一篇《SpringBoot源码分析(3)–Environment简介/prepareEnvironment准备环境(万字图文源码debug分析)》写完后还有些问题没分析完,此篇文章接着上一篇继续讲。

本文基于spring-boot-2.2.14.BUILD-SNAPSHOT源码分析Environment及配置文件加载原理。

二、Spring Boot 配置优先级

上一篇文章源码分析中有体现过配置的优先级,此处做一下总结。

以下是常用的 Spring Boot 配置形式及配置属性加载的顺序(优先级由高到低):

  1. 命令行参数,如 java -jar springboot.jar --name="Java项目"
  2. 命令行中的 SPRING_APPLICATION_JSON 指定参数, 如 java -Dspring.application.json='{"name":"Java技术栈"}' -jar springboot.jar
  3. servletConfigInitParams 初始化参数;
  4. servletContextInitParams 初始化参数;
  5. JNDI参数(如 java:comp/env/spring.application.json);
  6. systemPropertiesJava系统参数(来源:System.getProperties()或者(-d命令行参数));
  7. systemEnvironment操作系统环境变量参数;
  8. RandomValuePropertySource 随机数,仅匹配:ramdom.*
  9. profile配置文件(`application-{profile}.properties(YAML)
  10. 配置文件(`application.properties(YAML)
  11. @Configuration 注解类上的 @PropertySource 指定的配置文件
  12. 通过SpringApplication.setDefaultProperties 指定的默认属性

以上所有形式的配置都会被加载,当存在相同配置内容时,高优先级的配置会覆盖低优先级的配置;存在不同的配置内容时,高优先级和低优先级的配置内容取并集,共同生效,形成互补配置。

我们这里说的高优先级的配置会覆盖低优先级的配置,其实原理是加载属性配置时按优先级读取配置,当读取到配置后即返回。所以给人的感觉是高优先级覆盖了低优先级。

2.1、配置文件加载优先级

我们在项目中使用最多的配置文件是application.properties、application.yml、application-test.yml等文件。此处我们讲解一下springboot加载这些配置文件的优先级。

springboot启动时默认扫描下面四个目录,优先级如下(优先级从高到低):

  1. file:./config/ ( 项目根路径下的config文件夹)
  2. file:./ (项目根路径)
  3. classpath:/config/ (类路径/resources下的config文件夹)
  4. classpath:/ (类路径/resources)

文件加载顺序如下:

  1. 先按优先级加载四个目录下的application文件,同一目录下propertites比yml优先。properties > xml > yml > yaml
  2. 然后按优先级加载四个目录下的application-{profile}文件,同一目录下propertites比yml优先。properties > xml > yml > yaml

注意:此处的加载顺序只是springboot加载文件时的顺序,并不是读取配置文件中属性的顺序。
SpringBoot源码分析(4)--Environment(下)/配置文件加载原理,springbooot原理,spring boot,springboot源码

配置属性加载顺序如下:

  1. 先按优先级加载四个目录下的application-{profile}文件,同一目录下propertites比yml优先。properties > xml > yml > yaml
  2. 然后按优先级加载四个目录下的application文件,同一目录下propertites比yml优先。properties > xml > yml > yaml

注意:此处的加载顺序才是Environment获取配置的顺序,即environment.getProperty(key)时的顺序
SpringBoot源码分析(4)--Environment(下)/配置文件加载原理,springbooot原理,spring boot,springboot源码
问题:为什么会有文件加载顺序与配置属性加载顺序两种顺序呢?

springboot默认是按照文件加载顺序,即遍历profile然后加载classpath:/,classpath:/config/,file:./,file:./config/四个目录下的properties、xml、yml、yaml文件,最后按profile为维度进行反转,所以文件加载的顺序与配置属性加载的顺序是相反的,具体原理可以看上一篇文章。

测试demo
如下图,当同时有application.propertites与application-{profile}.propertites文件时,我们可以看到属性加载时是以application-{profile}.propertites为优先的。
SpringBoot源码分析(4)--Environment(下)/配置文件加载原理,springbooot原理,spring boot,springboot源码

总结

1.加载目录优先级从高到低
file:./config/ :项目根目录找config文件夹下找配置文件。
file:./ :根目录下找配置文件
classpath:/config/ :resources下找cofnig文件夹下找配置文件。
classpath:/ :resources下找配置文件。

2.在同一个目录,application.yml和application.properties同时存在,先读取application.properties
文件优先级:properties > xml > yml > yaml

3.先读取到的配置文件,不会因为在后面其他目录再次读到同名的配置文件而被替换。以第一次读到的为准

4.有子module的工程,子module目录下的配置文件和子module目录下一层config目录的配置文件不会加载。只会加载resources下面的配置文件

2.2、如何加载外部配置文件

在实际业务使用中,我们可能遇到项目被打成jar包,然后将配置文件放在jar包外面,怎么能指定加载外部的配置文件呢?

springboot提供了一个配置属性spring.config.location,当配置了该值,则从该值中加载配置文件,否则从classpath:/,classpath:/config/,file:./,file:./config/这四个目录下加载文件。所以我们可以在启动命令中指定外部路径。

java  -jar ../java/*.jar --spring.config.location=../conf/application.yml,classpath:/configs/default.properties

注意事项:支持通过命令行参数的方式指定多个配置文件,使用英文半角 , 隔开即可。

如果你通过spring.config.location指定的不是一个文件而是一个目录,在路径最后务必添加一个"/"结束,然后结合spring.config.name进行组合配置文件,组合示例如下:

# 加载/configs/application.properties 或 /configs/application.yml(默认文件名)
java -jar project.jar --spring.config.location=classpath:/configs/

# 加载/configs/custome.properties 或 /configs/custome.yml
java -jar project.jar --spring.config.location=classpath:/configs/ --spring.config.name=custome

注意事项:spring.config.name该配置参数默认值为application,所以如果只是指定了spring.config.location并为目录形式,上面示例中会自动将spring.config.name追加到目录路径后,如果指定的spring.config.location并非是一个目录,这里会忽略spring.config.name的值。

上面内容中提出了一些新的概念,如命令行参数、启动参数、系统参数、系统环境参数等等。下面就稍微了解一下。

三、springboot常见的配置参数

3.1、命令行参数

--key=value的形式添加命令行参数

方式一: idea启动时添加
SpringBoot源码分析(4)--Environment(下)/配置文件加载原理,springbooot原理,spring boot,springboot源码
方式二: jar包启动时添加

java  -jar ../java/*.jar --spring.config.location=../conf/application.yml --logging.config=../conf/logback-spring.xml 

方式三: 启动类中添加参数

@SpringBootApplication
public class Demo3Application {
	public static void main(String[] args) {
	        //添加命令行参数
	        List<String> argsList = new ArrayList<>();
	        argsList.add("--spring.profiles.active=sit");
	        if (args != null) {
	            argsList.addAll(Arrays.asList(args));
	        }
	        SpringApplication.run(Demo3Application.class, StringUtils.toStringArray(argsList));
	}
}

SpringBoot源码分析(4)--Environment(下)/配置文件加载原理,springbooot原理,spring boot,springboot源码

3.2、System Properties与System Environment的区别

System Properties与System Environment的变量很相近,此处说明一下两者的区别。

System Environment 指的是操作系统的环境变量,而 System Properties 指的是java 程序jvm的系统变量

常见的JVM属性
SpringBoot源码分析(4)--Environment(下)/配置文件加载原理,springbooot原理,spring boot,springboot源码

3.3、系统参数(System Properties)

-Dkey=value的形式添加JVM参数

方式一: 在idea启动参数中添加
SpringBoot源码分析(4)--Environment(下)/配置文件加载原理,springbooot原理,spring boot,springboot源码
SpringBoot源码分析(4)--Environment(下)/配置文件加载原理,springbooot原理,spring boot,springboot源码
方式二: jar命令启动时添加

java -jar target/xxx.jar -Dserver.port=9090 -Dserver.context-path=/test

方式三: 代码中添加

在代码里通过System.setProperty(key, value)进行设置

在java中获取jvm的系统变量代码如下:

// 获取所有的环境变量
Properties properties = System.getProperties();
// 获取指定的环境变量 如java.class.path
String property = System.getProperty("java.class.path");

3.4、系统环境参数(System Environment)

在java中获取操作系统的环境变量的代码如下:

// 获取全部的环境变量
Map<String, String> systemEnvironment = System.getenv();
// 获取某个环境变量 比如:PATH
String path = System.getenv("PATH");

SpringBoot源码分析(4)--Environment(下)/配置文件加载原理,springbooot原理,spring boot,springboot源码

四、Environment读取配置属性

4.1、传统方式获取environment配置

1.springboot启动类,传统从environment中获取值的方式environment.getProperty

@SpringBootApplication(scanBasePackages = {"com.example"})
public class Demo3Application {


    public static void main(String[] args) {
        ConfigurableApplicationContext run = SpringApplication.run(Demo3Application.class,args);
        
        Environment environment = run.getEnvironment();
        System.out.println(environment.getProperty("server.port"));
        System.out.println(environment.getProperty("people.man.name"));
    }
}

2.application.yml

server:
  port: 8080

people:
  man:
    name: 张三
    age: 12

a.b.my-first-key: hello spring environment

4.2、SpringBoot2.X 引入更强大的Binder获取environment配置方式

1.先看一个简单的示例,如何使用Binder绑定environment环境变量

@SpringBootApplication(scanBasePackages = {"com.example"})
public class Demo3Application {


    public static void main(String[] args) {
        ConfigurableApplicationContext run = SpringApplication.run(Demo3Application.class,args);
        
        Environment environment = run.getEnvironment();
         //此处调用Binder.get方法获取一个Binder
        Binder binder = Binder.get(environment);
         Integer port = binder.bind("server.port", Integer.class).get();
        //bind绑定yml文件中的配置key到一个具体的对象中
        People people= binder.bind("people.man", People.class).get();
        System.out.println(port);
        System.out.println(people.toString());
    }
}

输出结果:

8080
People(name=张三, age=12)

通过以上示例,我们可以看到Binder可以很方便的动态绑定对象,类型转换。Binder还可以绑定Map,list等。我们可以发现源码中也有很多地方使用了Binder绑定配置对象,是一个非常好用强大的类。文章来源地址https://www.toymoban.com/news/detail-549212.html

到了这里,关于SpringBoot源码分析(4)--Environment(下)/配置文件加载原理的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • SpringBoot配置文件的加载顺序

    一、引言 如果我们了解SpringBoot配置文件的加载顺序,对项目的开发和部署会有很大的帮助。举个工作中的例子,我们的项目是微服务架构模式,用Nacos做注册中心(可以配置每个微服务),所有服务请求需要通过网关,由网关做统一的鉴权和路由转发。环境有三套,本地环境

    2024年02月02日
    浏览(84)
  • SpringBoot 配置文件加载优先级

    最近在使用k8s部署项目的时候,发现Dockerfile文件中的命令后面跟的参数,无法覆盖nacos中的参数,今天有时间正好来整理一下Springboot配置的加载顺序 整理加载顺序第一个肯定看官方文档:https://docs.spring.io/spring-boot/docs/2.2.9.RELEASE/reference/htmlsingle/#boot-features-external-config 看不懂我们直

    2024年02月02日
    浏览(40)
  • SpringSecurity源码分析(一) SpringBoot集成SpringSecurity即Spring安全框架的加载过程

          Spring Security是一个强大的并且高度可定制化的访问控制框架。 它基于spring应用。 Spring Security是聚焦于为java应用提供授权和验证的框架。像所有的spring项目一样,Spring Security真正的强大在于可以非常简单的拓展功能来实现自定义的需求。       在分析SpringBoot集成的Sp

    2024年02月03日
    浏览(44)
  • Spring Security OAuth Client配置加载源码分析

    相关文章: OAuth2的定义和运行流程 Spring Security OAuth实现Gitee快捷登录 Spring Security OAuth实现GitHub快捷登录 Spring Security的过滤器链机制 这一节我们以前面默认的OAuth2 客户端集成为例,来了解下配置文件的加载,示例见第二、第三节。 假如你没有看过相关视频,或者书,但想要

    2024年02月08日
    浏览(36)
  • SpringBoot 启动配置文件加载和参数配置修改问题

    SpringBoot 或者SpringCloud 有配置文件加载和参数修改的机制,本文将从两个角度阐述参数修改和配置文件启动覆盖问题。 以下几种方式都可以被@Value读取到 java -jar -Dserver.port=8080 -Xms1024m demo.jar java -jar demo.jar --server.port=8080 从操作系统的环境变量中读取 通过项目中配置文件boots

    2023年04月15日
    浏览(45)
  • 10SpringBoot 静态资源访问 11Springboot的默认配置文件和外部配置文件及加载顺序

            做web开发的时候,我们往往会有很多静态资源,如html、图片、css等。那如何向前端返回静态资源呢?        以前做过web开发的同学应该知道,我们以前创建的web工程下面会有一个webapp的目录,我们只要把静态资源放在该目录下就可以直接访问。        但是,基

    2023年04月08日
    浏览(57)
  • SpringBoot项目加载配置文件的6种方式

    目录 1、通过@value注入 2、通过@ConfigurationProperties注入 3、通过框架自带对象Environment实现属性动态注入 4、通过@PropertySource注解实现外部配置文件注入属性值 5、yml 外部配置文件动态注入 6、Java原生态方式注入属性值 满足条件: 1、该类首先要被SpringBoot框架管理,属于SpringB

    2024年02月11日
    浏览(31)
  • SpringBoot源码解读与原理分析(五)SpringBoot的装配机制

    前面三小节分别介绍了Spring Framewoek的模块装配、条件装配和SPI机制。下面正式进入Spring Boot的装配机制。 实际上, Spring Boot的自动装配是模块装配+条件装配+SPI机制的组合使用 ,而这一切都凝聚在Spring Boot主启动类的@SpringBootApplication注解上。 @SpringBootApplication注解是由三个注

    2024年02月19日
    浏览(47)
  • 【springboot test】springboot 单元测试配置文件加载顺序及覆盖关系

    参照目录结构: 1.配置文件加载基础原则: 通过任意方式指定的application-xxx.yml中会覆盖application.yml中同名配置,application.yml一般作为兜底或通用配置 2.application.yml主配置文件加载原则: [ 实际运行的application.yml ] = [ test/resources/application.yml ] ? [ test/resources/application.yml ] : [ main/reso

    2024年02月13日
    浏览(35)
  • 112、SpringBoot中配置文件的加载顺序是怎样的?

    优先级从高到低,高优先级的配置覆盖低优先级的配置,所有配置会形成互补配置。 命令行参数。所有的配置都可以在命令行上进行指定 Java系统属性(System.getProperties()); 操作系统环境变量; jar包外部的application-{profile}.properties或application.yml(带spring.profile)配置文件 jar包内部的

    2024年02月15日
    浏览(30)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包