SpringBoot——外部配置


基于SpringBoot v2.2.4.RELEASE 官方文档

外部配置

Spring Boot中可以使用外部配置,以便在不同的环境中使用相同的代码。你可以使用 properties 文件、YAML 文件、环境变量命令行参数 来配置。

1、配置随机值

RandomValuePropertySource 在注入随机值时是十分有用的。例如进入隐私的或者测试的例子。它可以产生整数、longs、uuid或字符串,如下所示:

my.secret=${random.value}
my.number=${random.int}
my.bignumber=${random.long}
my.uuid=${random.uuid}
my.number.less.than.ten=${random.int(10)}
my.number.in.range=${random.int[1024,65536]}

random.int* 语法可以带有参数。

  • random.int
  • random.int(value)
  • random.int(value, max) ——如果有maxvalue提供的就是最小值。valuemax 都是整数。

2、命令行配置属性

所有的属性配置都可以在命令行上进行指定。例如:

java -jar spring-boot-02-config-02-0.0.1-SNAPSHOT.jar --server.port=8087  --server.context-path=/abc

默认情况下,SpringApplication将所有命令行选项参数转换为a property并将其添加到Spring Environment

如果不希望将命令行属性添加到Environment,可以使用SpringApplication.setAddCommandLineProperties(false)来禁用。

3、Application Property 文件

SpringApplication从以下位置的application.properties文件中加载属性,并将其添加到Spring Environment

  1. 当前目录的一个 /config 子目录下(file:./config/);
  2. 当前目录(file:./);
  3. 类路径的 /config 包(classpath:/config/);
  4. 类路径下(classpath:/

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

可以使用YAML(.yml)来代替 .properties

如果不喜欢application.properties作为配置文件的名称,可以通过指定 spring.config.name 来使用另一个文件名。另外,还可以配置 spring.config.location 来改变默认的配置文件位置。

#指定其他文件名
$ java -jar myproject.jar --spring.config.name = myproject

项目打包好以后,我们可以使用命令行参数的形式,启动项目的时候来指定配置文件的新位置。

如果要指定配置文件和默认加载的这些配置文件共同起作用形成互补配置,需要使用spring.config.additional-lacation

#指定配置文件加载位置,如果有多个,用逗号隔开
$ java -jar spring-boot-02-config-02-0.0.1-SNAPSHOT.jar --spring.config.location=G:/application.properties

配置文件是以相反的顺序搜索。默认情况下,configured locationsclasspath:/,classpath:/config/,file:./,file:./config/。但搜索顺序的结果正好相反。

当通过 spring.config.lacation 自定义配置位置后,它们就会取代默认位置。并且如果spring.config.location配置为classpath:/custom-config/,file:./custom-config/,则搜索顺序将变为:

  1. file:./custom-config/
  2. classpath:custom-config/

当使用spring.config.additional-location配置时,除了默认位置外,还会使用配置的值。

  1. 可以在一个配置文件中指定默认值,然后在另一配置文件中选择性的覆盖这些值。
  2. 如果你使用 environment变量而不是 system 属性,大多数操作系统都不允许使用.分割的键名,这是可以使用_ 代替。(SPRING_CONFIG_NAME代替spring.config.name)。

4、profile

Profile可以为不同环境提供不同配置,可以通过激活、指定参数等方式快速切换环境。

在编写配置文件时,文件名可以是 application-{profile}.properties。默认使用application-default.properties(即application.properties)加载属性。

application-{profile}.properties文件能够从application.properties 的位置加载。

不论application-{profile}.properties 文件是在jar包外还是内部,他都可以覆盖application.properties

用法:

指定两种环境,分别为dev 和 prod:

#application-dev.properties
server.port=8081
#application-prod.properties
server.port=8082

激活profile有三种方法:

  1. 配置文件中指定

    #application.properties
    spring.profiles.active=dev	#启动后端口号为8081
    
  2. 命令行指定

    java -jar spring-boot-02-config-0.0.1-SNAPSHOT.jar --spring.profiles.active=dev;
    

    也可以在idea启动前,配置传入参数:

在这里插入图片描述

  1. 虚拟机指定

    如上图

5、加密属性值

Spring Boot不提供任何内置的对属性值加密的支持。

6、YAML的使用

Spring Framework提供了两个方便的类来加载YAML文件。

  • YamlPropertiesFactoryBean 将YAML 加载为 Properties
  • YamlMapFactoryBean 将YAML 加载为 Map

6.1 YAML语法

environments:
    dev:
        url: https://dev.example.com
        name: Developer Setup
    prod:
        url: https://another.example.com
        name: My Cool App

以上的YAML文档将会转化为以下properties:

environments.dev.url=https://dev.example.com
environments.dev.name=Developer Setup
environments.prod.url=https://another.example.com
environments.prod.name=My Cool App

List表示:

my:
   servers:
       - dev.example.com
       - another.example.com

以上的YAML文档将会转化为以下properties:

my.servers[0]=dev.example.com
my.servers[1]=another.example.com

6.2 多文档块方式

server:
  port: 8081
#spring:
#  profiles:
#    active: dev
---
server:
  port: 8082
spring:
  profiles: dev
---
server:
  port: 8083
spring:
  profiles: prod

在上面的例子中,如果dev配置文件处于活动状态,则server.port属性为8082。如果prod配置文件处于活动状态,则server.port属性为8083。上面的文档中spring.profiles.active 注释了,因此server.port属性为8081

6.3 YAML的缺点

不能通过@PropertySource 来加载YAML配置文件,所以如果想要通过这种方式加载值,只能使用properties 文件。

#person.properties
person.name: zhangsan
person.age: 10
person.address: 陕西省
person.birthday: 2017/10/20
@Component
@PropertySource(value = {"classpath:person.properties"})
@ConfigurationProperties(prefix = "person")
public class Person {

    private String name;
    private int age;
    private String address;
    private Date birthday;
  	//...省略getter和setter方法
}

在profile中使用YAML的多文档块方式可以会出现问题。

官方建议不要混合使用 YAML格式的profile文档YAML的多文档块 ,坚持只使用其中一个。

7、配置属性的类型安全

7.1 配置文件注入JavaBean

#application.yml
person:
    lastName: hello
    age: 18
    boss: false
    birth: 2017/12/12
    maps: {k1: v1,k2: 12}
    lists:
      - lisi
      - zhaoliu
    dog:
      name: 小狗
      age: 12
/**
 * 将配置文件中配置的每一个属性的值,映射到这个组件中
 * @ConfigurationProperties:告诉SpringBoot将本类中的所有属性和配置文件中相关的配置进行绑定;
 *      prefix = "person":配置文件中person下面的所有属性进行一一映射
 *
 * 使用@Component将该类称为容器中的组件
 * 只有这个组件是容器中的组件,才能使用容器提供的@ConfigurationProperties功能;
 *
 */
@Component
@ConfigurationProperties(prefix = "person")
public class Person {

    private String lastName;
    private Integer age;
    private Boolean boss;
    private Date birth;

    private Map<String,Object> maps;
    private List<Object> lists;
    private Dog dog;
  	//...省略getter和setter方法
}

可以通过 properties文件YAML文件外部环境变量等配置。

通常情况下,getters/setters 是强制要求的,因为值的绑定是通过标准的 Java Beans 属性描述符实现的。在下列情况中,setter 才可以忽略:

7.2 构造函数绑定

测试出现问题

7.3 @ConfigurationProperties

7.4 松散绑定

SpringBoot使用松散的规则将 properties 绑定到 @ConfigurationProperties 注解的beans上。

常见的例子包括

  • user-name 绑定到 userName
  • PORT 绑定到 port

现有以下 @ConfigurationProperties 注解的类

@Component
@ConfigurationProperties(prefix="person")
public class person {

    private String firstName;

    public String getFirstName() {
        return this.firstName;
    }

    public void setFirstName(String firstName) {
        this.firstName = firstName;
    }

}

使用上面的的代码,下面的这些 properties 名称都能够使用:

Properties描述
person.first-name短横线命名,建议在.properties.yml文件中使用
person.firstName标准驼峰式命名
person.first_name下划线表示法,是在.properties.yml文件中使用的另一种格式。
PERSON_FORSTNAME大写的格式,通常使用于系统环境变量

prefix 的值必须使用 短横线命名法 (小写字母,以-分隔开,例如 acme.my-project.person

不同属性的松散绑定规则
Property Source简单List
Properties文件短横线命名,驼峰式命名 或 下划线表示法使用[ ]或逗号分隔的标准列表语法
YAML文件短横线命名,驼峰式命名 或 下划线表示法YAML列表语法或者逗号分隔的值
环境变量_作为定界符的大写格式,_不应在属性名称中使用下划线括起来的数值,例如 MY_ACME_1_OTHER = my.acme[1].other
系统属性短横线命名,驼峰式命名 或 下划线表示法使用[ ]或逗号分隔的标准列表语法

7.5 @ConfigurationProperties数据校验

如果 @ConfigurationProperties 标注的类被 @Validated 注解,SpringBoot就会对该类的数据进行校验。

你能够直接使用 JSR-303 数据校验。

@Component
@ConfigurationProperties(prefix = "person")
@Validated
public class Person {
    @Email	//必须是邮箱
    private String email;
  	@NotNull	//不能为null
    private InetAddress remoteAddress;
}

为了确保嵌套属性的验证,相关的字段必须使用 @Valid 注解,示例:

/*Dog.java*/
public class Dog {

    private Long id;
    @Email
    private String name;
    private String type;
  	//...省略getter和setter方法
}
/*Person.java*/
@Component
@ConfigurationProperties(prefix = "person")
@Validated
public class Person {
    @NotNull
    private String name;
    private int age;
    private String address;
    private Date birthday;

    @Valid
    private Dog dog = new Dog();
  
  	//...省略getter和setter方法
}

你可以通过创建一个名为configurationPropertiesValidator 的bean自定义Spring 的Validator ,该@Bean 的方法应该声明为static

7.6 @ConfigurationProperties与@Value

@ConfigurationProperties@Value
功能批量注入配置文件中的属性一个个指定
松散绑定支持不支持
SpEL不支持支持
JSR303数据校验支持不支持
复杂类型封装支持不支持

如果我们只是在某个业务逻辑中需要获取一下配置文件中的某项值,使用@Value

如果我们专门编写了一个javaBean来和配置文件进行映射,我们就直接使用@ConfigurationProperties

最后,虽然你能够在@Value 写一个SPEL 表达式,但从application property 文件中获取的属性表达式不能处理。

@Value("${person.Name}")	//可以获取到properties中的值
private String name;
@Value("${person.age * 2}")	//可以获取到值,但不能处理,该处报错!!!
private int age;

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值