Spring Boot(06)——参数配置机制

简介:

参数配置机制

Spring Boot默认会读取Classpath根路径下的application.properties文件和application.yml文件作为配置文件(使用properties文件还是yaml文件就看个人的喜好了,就笔者而言,yaml文件结构更好,看起来更加的直观),并把它们封装到Environment对象。在应用中通过注入Enviroment对象就可以获取到application.properties中定义的所有的属性,也可以直接定义属性占位符进行属性值注入。假设在application.yml文件中进行了如下定义,其中test.prop.c的值中又使用了占位符test.prop.a,这在原Spring中也是支持的语法。

test.prop:
  a: valueA
  b: valueB
  c: ${test.prop.a}C

在Spring Boot应用中有如下这样一个bean定义,它有propA、propB和propC一个三个属性,需要分别从Environment中通过test.prop.atest.prop.btest.prop.c进行注入。

import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
import lombok.Data;

@Component
@Data
public class PropResolveSample {

    @Value("${test.prop.a}")
    private String propA;
    
    @Value("${test.prop.b}")
    private String propB;
    
    @Value("${test.prop.c}")
    private String propC;
    
}

这些参数都是可以正常注入的,而且值的来源就来自于定义在application.yml文件中的参数定义,以下是基于Spring Boot和Junit的单元测试代码,可以正常通过。

@SpringBootTest(classes=Application.class)
@RunWith(SpringJUnit4ClassRunner.class)
public class PropResovleTest {

    @Autowired
    private PropResolveSample propResolveSample;
    @Autowired
    private Environment enviroment;
    
    @Test
    public void test() {
        Assert.assertEquals("valueA", this.propResolveSample.getPropA());
        Assert.assertEquals("valueB", this.propResolveSample.getPropB());
        Assert.assertEquals("valueAC", this.propResolveSample.getPropC());
        
        Assert.assertEquals("valueA", this.enviroment.getProperty("test.prop.a"));
        Assert.assertEquals("valueB", this.enviroment.getProperty("test.prop.b"));
        Assert.assertEquals("valueAC", this.enviroment.getProperty("test.prop.c"));
    }
    
}

其实Spring Boot默认读取的配置文件的位置不仅仅是Classpath根路径,还包括Classpath下的/config路径,当前文件路径和当前文件路径下的config目录。即Spring Boot默认会读取classpath:/application.propertiesclasspath:/config/application.propertiesfile:./application.propertiesfile:./config/application.properties。当这四个路径下都同时存在application.properties文件时,每个application.properties文件都会读取,属性优先级将按照如下顺序,即后面的会覆盖前面的,如果每个路径下的application.properties文件中都定义了一个app.name属性,最终将以file:./config/application.properties中定义的为准。

  • classpath:/
  • classpath:/config/
  • file:./
  • file:./config/

可以通过系统属性spring.config.location来改变读取默认的配置文件的路径,如果有多个路径,多个路径可以使用英文逗号分隔。指定时可以指定的是具体的配置文件路径,也可以是配置文件所在的目录,如果配置的是目录应该以/结尾。同时指定了多个配置文件时后面的配置文件的属性优先级更高。

java -jar myproject.jar --spring.config.location=classpath:/default.properties,classpath:/override.properties`

配置文件的名称默认是application,如有需要也可以通过系统属性spring.config.name来更改。通过系统属性spring.config.location指定了配置文件的读取路径后将不再读取默认路径下的配置文件了,如果需要在读取默认位置下的配置文件的同时读取自定义的配置文件,可以使用spring.config.additional-location系统属性进行追加。使用spring.config.additional-location系统属性追加的配置文件的属性值的优先级将高于默认位置下的配置文件中的属性值,且同时追加多个配置文件时后面的配置文件的优先级更高。

关于配置文件路径的更多信息可以参考https://docs.spring.io/spring-boot/docs/2.0.3.RELEASE/reference/htmlsingle/#boot-features-external-config-application-property-files

随机数占位符

在配置占位符时,可以使用一个特殊的占位符,它以random.开头,之后可以接int、long、uuid等。其中int和long后还可以接参数指定范围,比如random.int(10)表示取10以内的随机数,random.int(10,20)表示取10-20的随机数,取出来的随机数会大于等于10,但是会小于20。随机数占位符会由org.springframework.boot.env.RandomValuePropertySource进行处理。该随机数占位符可以在application.yml文件中使用,也可以直接在bean定义的时候使用。下面的第一段代码就是直接在YAML文件中定义的,而第二段代码的最后两个属性值的注入则是直接通过random占位符进行注入的。

test.random:
  int: ${random.int}
  int10: ${random.int(10)}
  int10-100: ${random.int(10,100)}
  long: ${random.long}
  long-100: ${random.long(100)}
  uuid: ${random.uuid}
  bytes: ${random.bytes}
@Component
@Data
public class RandomExample {

    @Value("${test.random.int}")
    private int randomInt;
    
    @Value("${test.random.int10}")
    private int randomInt10;
    
    @Value("${test.random.int10-100}")
    private int randomInt10_100;
    
    @Value("${test.random.long}")
    private long randomLong;
    
    @Value("${test.random.long100}")
    private long randomLong100;
    
    @Value("${test.random.uuid}")
    private String randomUUID;
    
    @Value("${test.random.bytes}")
    private String bytes;
    
    @Value("${random.int(1000)}")
    private int randomInt1000;
    
    @Value("${random.bytessss}")
    private String bytes2;
    
}

需要注意的是当random.后接的内容不是int、long或uuid时将随机产生一个16位的字节数组,并把它们转换为16进制。输出上面RandomExample对象的toString()会得到类似于下面这样的一个输出:

RandomExample(randomInt=-82870261, randomInt10=9, randomInt10_100=72, randomLong=5569034461519794446, randomLong100=35, randomUUID=be6141ed-afba-43a4-b484-c738f2bc9ce0, bytes=67e403a4d9bf57ea4c0fe53020bff74e, randomInt1000=629, bytes2=e8c741396012ee33060c0bfe1f5e2f52)

访问命令行参数

默认情况下命令行指定的可选参数,即以--开头指定的参数也会被添加到Environment中。比如指定命令行参数为--foo=bar,则可以从Environment中获取到属性foo的值为bar。如果不希望命令行指定的可选参数自动添加到Environment中,则可以通过SpringApplication的setAddCommandLineProperties(false)禁用它。

@SpringBootApplication
public class Application {

    public static void main(String[] args) {
        SpringApplication app = new SpringApplication(Application.class);
        app.setAddCommandLineProperties(false);
        app.run(args);
    }

}

profile特性的配置文件

除了加载默认的application.properties文件和application.yml文件外,Spring Boot还会尝试加载application-{profile}.properties文件和application-{profile}.yml文件,其中的profile是当前激活的profile,如果当前没有指定激活的profile,则默认激活的profile是default,则默认情况下还会加载application-default.properties或application-default.yml文件。当激活的profile是abc和def时,则还会尝试加载application-abc.properties文件、application-abc.yml文件、application-def.properties文件和application-def.yml文件。当通用的application.properties中定义的属性在application-{profile}.properties也有定义时,application-{profile}.properties中的将拥有更高的优先级,即profile特性的属性定义会覆盖默认的。在指定需要激活的profile时可以在application.properties文件中进行定义。比如下面代码指定了激活的profile是dev。也可以通过命令行参数--spring.profile.active=dev指定。

spring.profiles.active=dev

yml文件中分profile配置

多profile除了可以为不同的profile定义特殊的配置文件外,还可以把profile下特殊的配置定义在同一个application.yml文件中。yml文件中可以使用---来把配置信息分成多个不同的块,每个块可以使用spring.profiles来指定所属的profile。比如在下面的application.yml配置文件中定义了默认的app.ip为10.10.10.1,当激活的profile包含dev时app.ip的值为10.10.10.2,当激活的profile包含test时app.ip的值为10.10.10.3。

app:
  ip: 10.10.10.1

---

spring:
  profiles: dev
  
app:
  ip: 10.10.10.2
  
---

spring:
  profiles: test
  
app:
  ip: 10.10.10.3

参考文档

https://docs.spring.io/spring-boot/docs/2.0.3.RELEASE/reference/html/boot-features-external-config.html

(注:本文是基于Spring Boot 2.0.3所写)

目录
相关文章
|
7天前
|
监控 Java 应用服务中间件
高级java面试---spring.factories文件的解析源码API机制
【11月更文挑战第20天】Spring Boot是一个用于快速构建基于Spring框架的应用程序的开源框架。它通过自动配置、起步依赖和内嵌服务器等特性,极大地简化了Spring应用的开发和部署过程。本文将深入探讨Spring Boot的背景历史、业务场景、功能点以及底层原理,并通过Java代码手写模拟Spring Boot的启动过程,特别是spring.factories文件的解析源码API机制。
22 2
|
8天前
|
Java 开发者 微服务
手写模拟Spring Boot自动配置功能
【11月更文挑战第19天】随着微服务架构的兴起,Spring Boot作为一种快速开发框架,因其简化了Spring应用的初始搭建和开发过程,受到了广大开发者的青睐。自动配置作为Spring Boot的核心特性之一,大大减少了手动配置的工作量,提高了开发效率。
28 0
|
1月前
|
Java API 数据库
Spring Boot框架因其简洁的配置、快速的启动特性及丰富的功能集而备受开发者青睐
本文通过在线图书管理系统案例,详细介绍如何使用Spring Boot构建RESTful API。从项目基础环境搭建、实体类与数据访问层定义,到业务逻辑实现和控制器编写,逐步展示了Spring Boot的简洁配置和强大功能。最后,通过Postman测试API,并介绍了如何添加安全性和异常处理,确保API的稳定性和安全性。
37 0
|
25天前
|
Java API Spring
在 Spring 配置文件中配置 Filter 的步骤
【10月更文挑战第21天】在 Spring 配置文件中配置 Filter 是实现请求过滤的重要手段。通过合理的配置,可以灵活地对请求进行处理,满足各种应用需求。还可以根据具体的项目要求和实际情况,进一步深入研究和优化 Filter 的配置,以提高应用的性能和安全性。
|
12天前
|
缓存 IDE Java
SpringBoot入门(7)- 配置热部署devtools工具
SpringBoot入门(7)- 配置热部署devtools工具
25 2
 SpringBoot入门(7)- 配置热部署devtools工具
|
11天前
|
Java 数据库连接
SpringBoot配置多数据源实战
第四届光学与机器视觉国际学术会议(ICOMV 2025) 2025 4th International Conference on Optics and Machine Vision
38 8
|
8天前
|
Java 数据库连接 数据库
springboot启动配置文件-bootstrap.yml常用基本配置
以上是一些常用的基本配置项,在实际应用中可能会根据需求有所变化。通过合理配置 `bootstrap.yml`文件,可以确保应用程序在启动阶段加载正确的配置,并顺利启动运行。
16 2
|
8天前
|
存储 运维 安全
Spring运维之boot项目多环境(yaml 多文件 proerties)及分组管理与开发控制
通过以上措施,可以保证Spring Boot项目的配置管理在专业水准上,并且易于维护和管理,符合搜索引擎收录标准。
20 2
|
17天前
|
Java Spring
[Spring]aop的配置与使用
本文介绍了AOP(面向切面编程)的基本概念和核心思想。AOP是Spring框架的核心功能之一,通过动态代理在不修改原代码的情况下注入新功能。文章详细解释了连接点、切入点、通知、切面等关键概念,并列举了前置通知、后置通知、最终通知、异常通知和环绕通知五种通知类型。
28 1
|
20天前
|
Java Spring 容器
SpringBoot读取配置文件的6种方式,包括:通过Environment、@PropertySource、@ConfigurationProperties、@Value读取配置信息
SpringBoot读取配置文件的6种方式,包括:通过Environment、@PropertySource、@ConfigurationProperties、@Value读取配置信息
43 3