Spring Boot配置难得的使用解释说明(小猪佩奇:配置加载是有优先级的)

  1. 云栖社区>
  2. 博客>
  3. 正文

Spring Boot配置难得的使用解释说明(小猪佩奇:配置加载是有优先级的)

hello熊本 2018-03-22 14:38:51 浏览675
展开阅读全文

SpringBoot的所有配置项都是可以在官方文档找到的:官方配置详解
介绍:
Appendix A. Common application properties
Various properties can be specified inside your application.properties file, inside your application.yml file, or as command line switches. This appendix provides a list of common Spring Boot properties and references to the underlying classes that consume them.
(丰富的配置都可以被在application.properties、application.yml指定或者是命令行中切换,附录中提供了一些常用的配置List集合和这些配置的作用)
下面是附录的一部分
这里写图片描述
1、Property contributions can come from additional jar files on your classpath, so you should not consider this an exhaustive list. Also, you can define your own properties.
(配置的应用可以来自于你的classpath中的其他配置文件,你可以不参考附录中的配置,而去指定你自定义的配置)

2、This sample file is meant as a guide only. Do not copy and paste the entire content into your application. Rather, pick only the properties that you need.
(附录中的配置参数只是仅供参考的,不要整个粘贴复制到你项目中的配置项中去,更重要的是,需要去选择你需要修改的配置项进行合适的修改)

3、配置项的引用

在application.properties中的各个参数之间可以直接通过“${keyname}”引用来使用。
在application.properties中也可以通过“@keyname@”来引用pom文件中的元素节点值,例如:

3.1
pom文件中有如下定义:

<properties>
    <project.name >easy-springboot-demo </ project.name >
    <project.version>1.0</ project.version >
</properties>

3.2
则在application.properties文件中可以通过如下方式引用:

# 项目名称
com.easy.springboot.project.name = @project.name@
# 项目版本
com.easy.springboot.project.version = @project.version@

4、随机数属性value
在一些情况下,有些参数我们需要希望它不是一个固定的值,Spring Boot的属性配置文件中可以通过${random}来产生int值、long值或者string字符串,来支持属性的随机值。

# 随机字符串
com.easy.springboot.string=${random.value} 
# 随机int
com.easy.springboot.number=${random.int} 
# 随机long
com.easy.springboot.bignumber=${random.long} 
# 100以内的随机数
com.easy.springboot.range1=${random.int(100)} 
# 100-200的随机数
com.easy.springboot.range2=${random.int[100,200]}

5、属性配置文件的位置
spring会从classpath下的/config目录或者classpath的根目录查找application.properties或application.yml。
/config优先于classpath根目录。

6、Spring Boot 配置的管理
一般在一个项目中,总是会有好多个环境。比如:

开发环境 -> 测试环境 -> 预发布环境 -> 生产环境

6.1 在应用中管理配置是一个重要的问题,尤其是在应用需要部署到多个环境中时。通常会需要为每个环境提供一个对应的属性文件,用来配置各自的数据库连接信息、服务器信息和第三方服务账号等。通常的应用部署会包含开发、测试和生产等若干个环境。

6.2 常规情况下,我们都知道Spring Boot的配置会从application.properties中读取。实际上,从resource目录下的application.properties文件读取是Spring Boot配置链中的一环而已。

7、重点来了
Spring Boot提供了一种优先级配置读取的机制来帮助我们从这种困境中走出来。
Spring Boot 所提供的配置优先级顺序比较复杂。按照优先级从高到低的顺序,具体的列表(从高到低)如下所示。

1.命令行参数(优先级最高)。
2.通过 System.getProperties() 获取的 Java 系统参数。
3.操作系统环境变量。
4.从 java:comp/env 得到的 JNDI 属性。
5.通过 RandomValuePropertySource 生成的random.*属性。
6.jar包外部的application-{profile}.properties或application.yml(带spring.profile)配置文件,通过spring.config.location参数指定
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)配置文件
10.应用 Java配置类,包含@Configuration注解的 Java 类,通过@PropertySource注解声明的属性文件。
11.通过SpringApplication.setDefaultProperties声明的默认属性。

如果Spring Boot在优先级更高的位置找到了配置,那么它就会忽略优先级低的配置。下面我们简单讲讲这些优先级。

8、命令行参数配置
Spring Boot 的这个配置优先级看似复杂,其实是很合理的。命令行参数的优先级之所以被设置为最高,是因为可以方便我们在测试或生产环境中快速地修改配置参数值,而不需要重新打包和部署应用。
SpringApplication 类默认会把以“–”开头的命令行参数转化成应用中可以使用的配置参数,如 “–name=Alex” 会设置配置参数 “name” 的值为 “Alex”。
如果不需要这个功能,可以通过,禁用解析命令行参数。

SpringApplication.setAddCommandLineProperties(false)

9、random.*属性
RandomValuePropertySource 可以用来生成测试所需要的各种不同类型的随机值,从而免去了在代码中生成的麻烦。RandomValuePropertySource 可以生成数字和字符串。数字的类型包含 int 和 long,可以限定数字的大小范围。以“random.”作为前缀的配置属性名称由 RandomValuePropertySource 来生成,代码示例

user.id=${random.value}
user.count=${random.int}
user.max=${random.long}
user.number=${random.int(100)}
user.range=${random.int[100, 1000]}

10、属性文件配置
属性文件是最常见的管理配置属性的方式。Spring Boot 提供的 SpringApplication 类会搜索并加载 application.properties 文件来获取配置属性值。SpringApplication 类会在下面位置搜索该文件:

1.当前目录的/config子目录
2.当前目录
3.classpath 中的/config包
4.classpath

可以通过spring.config.name这个key的配置属性来指定不同的属性文件名称。
也可以通过spring.config.location来添加额外的属性文件的搜索路径。

spring.config.name=
spring.config.location=

对于配置属性,可以在代码中通过“@Value”来使用,例如

    @Value("${oss.accessKeyId}")
    private String ossAccessKeyId;

11、相对于application.properties,还有一个配置文件application.yml
相对于属性文件来说,YAML 是一个更好的配置文件格式。
当有前缀的情况下,使用.yml格式的配置文件更简单。
注意:使用.yml时,属性名的值和冒号中间必须有空格,如name: SpringBoot正确,name: SpringBoot就是错的。
YAML 在 Ruby on Rails 中得到了很好的应用。YAML是JSON的一个超集,也是一种方便的定义层次配置数据的格式。它的基本语法规则如下:

大小写敏感
使用缩进表示层级关系
缩进时不允许使用Tab键,只允许使用空格。
缩进的空格数目不重要,只要相同层级的元素左侧对齐即可
# 表示注释,从这个字符一直到行尾,都会被解析器忽略。

YML使用
只要你将SnakeYAML 库放到classpath下,SpringApplication就会自动支持YAML,以作为properties的替换。当然,我们通常不需要这么做,因为我们一般都会使用Starters,在spring-boot-starter里会自动加载SnakeYAML。

Spring框架提供两个便利的类用于加载YAML文档,YamlPropertiesFactoryBean会将YAML加载为Properties,YamlMapFactoryBean会将YAML加载为Map。

Spring Boot使用application.properties默认了很多配置。但需要自己添加一些配置的时候,我们应该怎么做呢。
例如,下面这段yml格式的配置

environments:
    dev:
        url: http://dev.easy.springboot.com
        name: Easy Spring Boot

会转化为:

environments.url=http://dev.easy.springboot.com
environments.name=Easy Spring Boot

配置文件.yml和.properties的相互转化
如果我们自定义了属性key,在代码中怎样使用上面的配置信息呢?
利用Spring DataBinder工具集,Spring Boot通过注解
@ConfigurationProperties 和@EnableConfigurationProperties 来完成这件事情。
例如:在代码中对应的Bean对象:

@ConfigurationProperties(prefix="environments")
public class EnvironmentsConfig { 
    private String url; 
    private String name;

    public String getUrl(){ return this.url; }  
    public void setUrl(String url){ this.url = url; }  
    public String getName(){ return this.name; } 
    public void setName(){ this.name = name; } 

}

数组配置的转化,例如:

my:
   servers:
       - dev1.easy.com
       - dev2.easy.com

会转化为:

my.servers[0]=dev1.easy.com
my.servers[1]=dev2.easy.com代码片

12、使用@ConfigurationProperties这个注解来实现属性Bean的绑定,需要在Bean里面添加一个java.util.List(或者Set)类型的属性,然后写好setter(setter也可以换成初始化一个对象),getter:

@ConfigurationProperties(prefix="my")
public class ServersConfig {
    private List<String> servers = new ArrayList<String>();//initialize it with a mutable value, equals a setter
    public List<String> getServers() {
        return this.servers;
    }    

}

因为YamlPropertySourceLoader类能够将YAML作为PropertySource导出到Spring Environment。所以我们可以使用常用的@Value注解配合占位符语法访问YAML属性。

另外,当我们使用@ConfigurationProperties注解定义配置的Bean时,需要在SpringBoot Application启动类上标注@EnableConfigurationProperties。

13、使用 Java配置类
Spring 框架本身提供了多种的方式来管理配置属性文件。Spring 3.1 之前可以使用 PropertyPlaceholderConfigurer。Spring 3.1 引入了新的环境(Environment)和概要信息(Profile)API,是一种更加灵活的处理不同环境和配置文件的方式。

Spring Profiles提供了一种隔离应用程序配置的方式,并让这些配置只在特定的环境下生效。任何@Component或@Configuration都能注解@Profile,从而限制加载它的环境:

@Configuration
@Profile("production")
public class ProductionConfiguration {

    // ...

}

指定的属性方式常用的有2种:

1.配置在application.properties中:

spring.profiles.active=production

2.或使用命令行开关:

--spring.profiles.active=production

当指定了属性后,就会决定ProductionConfiguration这个类是否生效了
如果应用中包含多个 profile,可以为每个 profile 定义各自的属性文件,按照application-{profile}.properties(.yml)来命名。
14、使用CommandLineRunner
实际应用中,有时候我们在项目服务启动的时候就去加载一些数据或做一些事情这样的需求。 以前比较常见的做法是写再static代码块中。

在Spring Boot中,它提供了一个CommandLineRunner接口,实现这个接口的类总是会被优先启动,并优先执行CommandLineRunner接口中提供的run()方法。例如

public class ApplicationConfigure implements CommandLineRunner { 
    @Override 
    public void run(String... strings) throws Exception {
        //TODO : 比如说,在这里预先加载的一些方法,类,属性等。
    }
}

如果有多个CommandLineRunner接口实现类,那么可以通过注解@Order
来规定所有实现类的运行顺序。
配置这个东西,真的是很重要。
ps:感谢一下下面的这位先行者
作者:东海陈光剑
链接:https://www.jianshu.com/p/5e8210f5e5a3
來源:简书

网友评论

登录后评论
0/500
评论
hello熊本
+ 关注