SpringBoot入门到精通:(三)配置文件

在这里插入图片描述

前言

Spring Boot使用“习惯优于配置”(项目中存在大量的配置,此外还内置了一个习惯性的配置,让你无需手动进行配置)的理念让你的项目快速运行起来。但是如果有些配置不符合我们的要求怎么办呢,这就需要了解Spring Boot的配置文件了。

正文

默认配置文件

SpringBoot使用一个全局的配置文件,配置文件支持properties和yml两种类型的配置,配置文件名是固定的application.properties/application.yml,Sping Boot的全局配置文件的作用是对一些默认配置的配置值进行修改。

配置文件的优先级

springboot 启动会扫描以下位置的application.properties/application.yml文件作为Spring boot的默认配置文件

  • –file:./config/ (项目的config文件夹下 )

  • –file:./ (直接放到项目路径下)

  • –classpath:/config/ (类路径下的config文件夹下)

  • –classpath:/ (直接放到类路径下)

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

SpringBoot会从这四个位置全部加载主配置文件;互补配置

配置文件占位符

1、随机数

配置文件中${random} 可以用来生成各种不同类型的随机值,从而简化了代码生成的麻烦,例如 生成 int 值、long 值或者 string 字符串。

randomtest:
  value: ${random.value}
  int: ${random.int}
  intarr: ${random.int(10)}
  long: ${random.long}
  longstr: ${random.long(10)}
  uuid: ${random.uuid}
2、占位符获取之前配置的值,如果没有可以s使用指定默认值
user: 
	user-name: 张三${random.uuid}
	age: ${random.int}
	birth: 2017/12/15	
	dog: 
		name=${user.hello:hello}_dog  //如果有user.hello,使用前面配置的user.hello的值,没有则使用默认值hello
		age=15

使用自定义配置文件

有时候我们不希望把所有配置都放在application.properties里面,那么我们就可以使用@PropertySource注解来加载指定的配置文件
我们可以自定义一个配置文件,比如user.properties,路径跟也放在src/main/resources下面。
我们就可以在配置类中使用@PropertySource注解来指定加载user.properties配置文件

@PropertySource(value = {"classpath:user.properties"})
@ConfigurationProperties(prefix = "user")
@Component
@Data
public class User {

    private String userName;
    private int age;
    private Date birthday;

}

注:@PropertySource注解不支持yml配置文件

外部配置-命令行参数配置

Spring Boot是基于jar包运行的,打成jar包的程序可以直接通过下面命令运行:

java -jar xx.jar

可以以下命令修改tomcat端口号:

java -jar xx.jar --server.port=8081

可以看出,命令行中连续的两个减号–就是对application.properties中的属性值进行赋值的标识。
所以java -jar xx.jar --server.port=8081等价于在配置文件中添加属性server.port=8081。
如果你怕命令行有风险,可以使用SpringApplication.setAddCommandLineProperties(false)禁用它。

实际上,Spring Boot应用程序有多种设置途径,Spring Boot能从多重属性源获得属性,包括如下几种:

  1. 命令行参数,所有的配置都可以在命令行上进行指定,多个配置用空格分开; --配置项=值

    java -jar spring-boot-02-config-02-0.0.1-SNAPSHOT.jar --server.port=8087  --server.context-path=/abc
    
  2. 来自java:comp/env的JNDI属性

  3. Java系统属性(System.getProperties())

  4. 操作系统环境变量

  5. RandomValuePropertySource配置的random.*属性值

    由jar包外向jar包内进行寻找;

    优先加载带profile

  6. jar包外部的application-{profile}.properties或application.yml(带spring.profile)配置文件

  7. jar包内部的application-{profile}.properties或application.yml(带spring.profile)配置文件**

    再来加载不带profile

  8. jar包外部的application.properties或application.yml(不带spring.profile)配置文件

  9. jar包内部的application.properties或application.yml(不带spring.profile)配置文件

  10. @Configuration注解类上的@PropertySource

  11. 通过SpringApplication.setDefaultProperties指定的默认属性

所有支持的配置加载来源;参考官方文档

配置文件值获取

SpringBoot有两种方式获取配置文件的值

使用@Value注解

配置文件中提供自定义属性的支持,这样我们就可以把一些常量配置在这里:

user:
  user-name: 张三
  age: 18
  birthday: 2000/01/01

然后直接在要使用的地方通过注解@Value(value=”${config.name}”)就可以绑定到你想要的属性上面

@Component
@Data
public class User{

    @Value("${user.user-name}")
    private String userName;
    @Value("${user.age}")
    private int age;
    @Value("${user.birthday}")
    private Date birthday;

}

测试运行,输出获取到的user

@RunWith(SpringRunner.class)
@SpringBootTest
public class SpringbootApplicationTests {
    @Autowired
    User user;
    @Test
    public void contextLoads() {
        System.out.println(user);
    }
}

输出结果如下

User(userName=张三, age=18, birthday=Sat Jan 01 00:00:00 CST 2000)

使用@ConfigurationProperties注解

有时候属性太多了,一个个绑定到属性字段上太累,我们可以使用@ConfigurationProperties 注解
该注解的含义是将配置文件中配置的每一个属性的值,映射到这个组件中,其属性prefix = "xxx"指定配置文件中哪个下面的所有属性进行一一映射
注:只有这个组件是容器中的组件,才能容器提供的@ConfigurationProperties功能;所以类上必须有@Component注解
这样我们就不必在每个属性上都配置@Value注解,只需要在类上配置@ConfigurationProperties(prefix = "user")
SpringBoot就会自动将每个属性都映射上配置文件中对应的值

@Component
@ConfigurationProperties(prefix = "user")
@Data
public class User{

    private String userName;

    private int age;

    private Date birthday;

}

测试运行,输出获取到的user

@RunWith(SpringRunner.class)
@SpringBootTest
public class SpringbootApplicationTests {
    @Autowired
    User user;
    @Test
    public void contextLoads() {
        System.out.println(user);
    }
}

输出结果如下

User(userName=张三, age=18, birthday=Sat Jan 01 00:00:00 CST 2000)

@Value和@ConfigurationProperties注解的区别
@ConfigurationProperties@Value
批量配置支持不支持
松散绑定(松散语法)支持不支持
SpEL不支持支持
JSR303数据校验支持不支持
复杂类型封装支持不支持
  1. 批量配置:如上面实例中所示,@ConfigurationProperties可以批量注入配置文件中的属性,@Value只能一个一个注入
  2. 松散语法:@ConfigurationProperties支持松散语法,比如配置文件中user-name使用@ConfigurationProperties可以给userName属性注入值,但是@Value("${user.userName}")不能将配置文件中的user-name属性赋值给userName
  3. SpEL语言:@value支持SpEL语言,比如:
    @Value("#{11*2}")
    private int age;
    
    但是如果在配置文件中age=#{11*2},@ConfigurationProperties并不能将计算后的值注入给age属性
  4. JSR303数据校验:使用@ConfigurationProperties可以使用数据校验,比如:
    @Email
    private String email;
    
  5. @ConfigurationProperties支持复杂性封装,比如
    user:
      user-name: 张三
      age: 18
      birthday: 2000/01/01
      map: {1:v1,k2:v2}
    
    @Component
    @ConfigurationProperties(prefix = "user")
    @Data
    public class User{
    
        private String userName;
    
        private int age;
    
        private Map map;
    
    }
    
    @ConfigurationProperties可以直接将配置文件中的map赋值给map属性

Profile-多环境配置

当应用程序需要部署到不同运行环境时,配置通常会有所不同,最简单的比如日志,生产日志会将日志级别设置为WARN或更高级别,并将日志写入日志文件,而开发的时候需要日志级别为DEBUG,日志输出到控制台即可。如果每次发布的时候替换掉配置文件,这样太麻烦了,Spring Boot的Profile就给我们提供了两种解决方案,命令带上参数就搞定。

1、多Profile文件

我们在主配置文件编写的时候,文件名可以是 application-{profile}.properties/yml
默认使用application.properties的配置,可以在配置文件中使用spring.profiles.active= xxx指定使用哪个配置文件
比如我们想使用application-dev.yml这个配置文件就可以在主配置文件中配置

spring:
  profiles:
    active: dev
2、yml支持多文档块方式

yml可以使用---来分割代码块,可以指定使用哪个代码块

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

---
server:
  port: 8084
spring:
  profiles: prod  #指定属于哪个环境

也可以使用外部参数激活使用哪个配置文件

java -jar spring-boot.jar --spring.profiles.active=dev;

或者使用虚拟机参数

-Dspring.profiles.active=dev
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值