SpringBoot--配置文件&Profile

727 阅读4分钟

配置文件读取优先级?

  • 同一个目录下,有.yml也有.properties,默认先读取.properties。
  • 不同目录下先后排序:
    • 1.config/application.properties(项目根目录中config目录下)
    • 2.config/application.yml
    • 3.application.properties(项目根目录下)
    • 4.application.yml
    • 5.resources/config/application.properties(项目resources目录中config目录下)
    • 6.resources/config/application.yml
    • 7.resources/application.properties(项目的resources目录下)
    • 8.resources/application.yml

外部配置文件读取优先级?

  1. 命令行参数。所有的配置都可以在命令行上进行指定;
  2. 来自java:comp/env的JNDI属性;
  3. Java系统属性System.getProperties()
  4. 操作系统环境变量 ;
  5. RandomValuePropertySource 属性类生成的 random.* 属性
  6. 打包在应用外的 application.properties(或 yml)文件
  7. 打包在应用内的 application.properties(或 yml)文件
  8. @Configuration注解类上的@PropertySource
  9. SpringApplication.setDefaultProperties 声明的默认属性

常用场景:第6条。在jar包同目录放置application.properties配置文件,优先级比jar内高。

目录说明

  • resources目录:编译后文件就在classpath(热部署的作用范围是classpath下。classpath就是编译后的target/classes目录)。所以一般配置文件都在resources目录
  • 非classpath下的配置文件在打包时,如果不做配置是不会打包进jar中的。所以只有resources/config/resources/目录下的会在jar包。

配置项覆盖、配置中心

  • 多个配置文件都配置了同一个属性,默认使用第1个读取到的,不会被后读取的覆盖。
  • 启动命令可以覆盖配置文件的配置,如:java -jar demo.jar --server.port=8088 --server.servlet.context-path=/api
  • 配置中心配置项优先级比任何都高,包括bootstrap.properties

怎么可以让配置中心不覆盖本地配置?

可以在远程配置文件中做配置,比如ncos的:

spring:
  cloud:
    config:
      # 如果本地配置优先级高,那么 override-none 设置为 true,包括系统环境变量、本地配置文件等配置
      override-none: true
      # 如果想要远程配置优先级高,那么 allow-override 设置为 false,如果想要本地配置优先级高那么 allow-override 设置为 true
      allow-override: true
      # 只有系统环境变量或者系统属性才能覆盖远程配置文件的配置,本地配置文件中配置优先级低于远程配置;注意本地配置文件不是系统属性
      override-system-properties: false

Spring Cloud 的 bootstrap.properties

  • 优先于application。所以不会被本地配置覆盖
  • 会被命令行参数覆盖。
  • 会被配置中心覆盖

详解

  • 启动上下文时,Spring Cloud会创建一个Bootstrap Context,作为Spring应用的Application Context的父上下文。初始化的时候
  • Bootstrap Context负责从外部源加载配置属性并解析配置。这两个上下文共享一个从外部获取的Environment。
  • Bootstrap属性有高优先级,默认情况下,它们不会被本地配置覆盖。
  • Bootstrap context和Application Context有着不同的约定,所以新增了一个bootstrap.yml文件,而不是使用application.yml (或者application.properties)。保证Bootstrap Context和Application Context配置的分离。

SpringBoot中的profile应用

配置文件件

通常一套程序会被应用和安装到几个不同的环境,比如:开发、测试、生产等。其中每个环境的数据库地址、服务器端口等配置都会不同,如果在为每个不同环境打包时都要修改配置文件的话,那将会是一件非常繁琐并且容易发生错误的事。

对于多环境的配置,各种项目构建工具或者是框架的基本思路是一致的,通过配置多份不同环境的配置文件,再通过打包命令指定需要打包的内容之后进行区分打包,Spring Boot也不例外,或者说更简单。

在Spring Boot中多环境配置文件名需要满足application-{proflie}.properties的格式,其中{profile}对应各种环境标识,比如:

  • application-dev.properties:开发环境
  • application-test.properties:测试环境
  • application-prod.properties:生产环境

bean加载

上面配置数据库连接时使用的是配置文件的方式,Spring中的Java Bean也可以通过@Profile注解来实现不同环境下的配置。只要有组件注解的类上都可以使用@Profile注解来表示在指定profile时才创建Bean,比如某个Service要求在不同环境下返回不同的内容,此时实现代码如下:

@Service
@Profile("dev")
public class MyService{
    public void test(){
        // ...
    }
}

@Service
//@Profile是可以有多个值的。
@Profile(value= {"test","prod"})
public class MyService2{
    public void test(){
        // ...
    }
}

激活指定profile

常用的激活profile的方式有如下两种:

  • 在application.properties文件中通过spring.profiles.active属性来设置,其值对应{profile}值。如:spring.profiles.active=dev就会加载application-dev.properties配置文件中的内容。一般application.properties中写入公共的配置,而application-{profile}.properties中写入各自profile环境下的配置。
  • 通过--来添加命令行参数,如下:java -jar xxx.jar --spring.profiles.active=prod可以加载application-prod.properties。