SpringBoot基础 SpringBoot系列之配置文件详解篇 2021-04-09 [TOC] # Spring Boot的配置文件详解 ## 一、本章目的 了解并学习SpringBoot的核心配置文件及自定义配置文件的使用。 ## 二、核心配置文件 核心配置文件是我们用的比较频率最高的一种配置方式,核心配置文件使用key-value的形式来进行配置。其中key主要分为两种: - 默认属性:根据[官方提供的配置文件](https://docs.spring.io/spring-boot/docs/2.4.4/reference/htmlsingle/#common-application-properties "官方提供的配置文件")可配置列表进行修改,SpringBoot将自动读取配置和初始化。 - 自定义属性:根据需求任意编写,但是需要自行读取配置和初始化。 ### 1.1添加默认属性 以数据库配置为例,在application.yml配置文件中添加如下: ```yaml spring: datasource: url: jdbc:mysql://127.0.0.1:3306/douban?serverTimezone=GMT%2B8 username: root password: root driver-class-name: com.mysql.cj.jdbc.Driver ``` ### 1.2添加自定义属性 在 application.yml配置文件中添加一个用户的信息如下: ```yaml user: userName: ${aaa:张三}//三元式占位,如果aaa属性存在则取其值,否则使用默认“张三” age: 18 birthday: 1991/01/01 address: {province: 陕西, city: 西安, zone: 雁塔区} skills: [Java, Python] ``` 同时,spring boot也支持在系统加载的时候配置随机数: ```yaml user: random: secret: ${random.value} #随机32位MD5字符串 intNumber: ${random.int} #随机int数字 longNumber: ${random.long} #随机long数字 uuid: ${random.uuid} #随机uuid lessTen: ${random.int(10)} #随机10以内的数字 range: ${random.int[1024,65536]} #随机1024~65536之内的数字 ``` ### 1.3读取核心配置文件 #### 1.3.1使用@ConfigurationProperties批量读取属性,支持两种方式 - ①加在类上,需要与@Component(或@Configuration)结合使用并提供getter和setter方法 ```java @Component //让该类被spring的IOC容器管理,也可以使用@Configuration @ConfigurationProperties(prefix = "user") // 通过prefix来绑定对应的属性 public class User { private String userName; private int age; private Date birthday; private Map<String, Object> address; private String[] skills; // 省略getter和setter方法 } ``` - ②加在方法上,通过@Bean的方式进行声明,如在启动类声明,代码如下: ```java @SpringBootApplication public class DemoApplication { @Bean @ConfigurationProperties(prefix = "user") public User User() { return new User(); } public static void main(String[] args) { SpringApplication.run(DemoApplication.class, args); } } ``` > SpringBoot读取默认配置时也是使用了@ConfigurationProperties这个注解 #### 1.3.2使用@Value读取单个属性 还是用上面那个用户信息的例子来说明如何使用@Value,我们编写一个绑定类。 ```java @Component public class User { @Value("${user.userName}") private String userName; @Value("99") private int age; // 省略getter和setter方法 } ``` > 注:只需要在需要注入的属性或者setter方法上加上@Value("${xxx}")或者@Value(“xxx”),就可以将配置文件中的值注入到绑定类中,并且还可以将任意值注入属性。 #### 1.3.3@ConfigurationProperties和@Value的区别 ![](/uploads/1/image/public/202104/20210409184344_n2banwcecl.png) > **松散语法:**java文件中的属性名为userName,为标准的驼峰命名方式,。我们在yml或者properties中可以不采用驼峰命名方式,而是使用user-name。这样也可以注入成功,这就是松散语法。 ## 三、自定义配置文件读取@PropertySource 在项目开发中,我们有时会将与项目相关的一些配置信息保存到单独的配置文件中,这时我们可以使用@PropertySource注解来读取我们自定义的配置文件。 如我们在resources下新建一个config.properties2文件,并写入以下内容: ```yaml user.user-name=李四 user.age=27 user.birthday=1991/02/01 user.address.province=陕西 user.address.city=西安 user.address.zone=新城区 user.skills[0]=Java user.skills[1]=JavaScript ``` > 我们知道SpringBoot只会默认读取application.properties和application.yml中的配置。 为了让SpringBoot读取到我们的配置,我们需要在绑定类上加一个@PropertySource注解, 并指明我们自定义配置文件的位置。 ```java @Component //该类会被注入到Spring容器中 @ConfigurationProperties(prefix = "user")//批量读取以“user”开头的属性 @PropertySource("classpath:config.properties") //读取自定义配置文件(相对路径resources下) public class User { private String userName; private int age; private static Date birthday; private Map<String, Object> address; private String[] skills; // 省略getter和setter方法 } ``` > 注意:如果要使用自定义配置文件,必须使用.properties文件格式,目前(2.4.4版本)@PropertySource还不支持读取.yml格式的自定义配置文件。 ## 四、spring boot多环境设置及切换 我们在实际工作中,会存在很多套环境,例如开发环境、测试环境、生产环境。程序在不同的环境下可能会有不同的配置,例如数据库的连接、日志的级别等等。 使用Spring Boot的Profile可以实现多场景下的配置切换,方便开发中进行测试和部署生产环境。 ### 3.1使用profile配置不同环境的properties配置文件 - 使用properties文件进行多个环境的配置,如创建若干个application-{profile}.properties文件用于存放不同环境特有的配置,将与环境无关的配置存放在application.properties文件中。 - application.properties文件中通过**spring.profiles.active=xxx**指定加载不同环境的配置。 - 如果不指定,则默认加载application.properties的配置,不会加载带有profile的配置。 **以端口为例:** 开发环境需要使用8081端口,生产环境需要使用8082端口,分别为开发环境和生产环境创建application-dev.properties和application-pro.properties文件 ![](/uploads/1/image/public/202104/20210409190303_p3u8wbcxqq.png) 在application-dev.properties中使用server.port=8081设定端口号为8081,同理,在application-pro.properties中使用server.port=8082。需要切换端口时,只需要在application.properties中指定我们需要使用的配置文件即可:**spring.profiles.active=dev** ### 3.2使用yml配置文件 使用yml文件配置多套环境的原理与properties相同,只是我们也可以不建多个配置文件,只需在application.yml配置文件中通过“---”进行分隔不同环境的配置,通过spring:profiles:active指定 ```yaml server: port: 8081 spring: profiles: active: pro #指定使用哪个配置 --- server: port: 8082 spring: profiles: dev --- server: port: 8083 spring: profiles: pro ``` > 但是,当一个配置文件中写的内容太多时,不利于我们后期的维护,则建议像properties文件一样,写多个yml,按照application-{profile}.yml来命名,并且在application.yml中指定使用哪个配置文件即可 ### 3.3使用命令行切换环境 在SpringBoot时,将项目打成jar包部署到服务器上,启动时我们只要加上一行**--spring.profiles.active=xxx**命令,就可以控制我们使用哪个环境的配置,非常方便。 完整命令如下: ```java java -jar xxx.jar --spring.profiles.active=dev #表示使用开发环境的配置 java -jar xxx.jar --spring.profiles.active=pro #表示使用生产环境的配置 ``` ## 五、核心配置文件的位置以及优先级 - spring boot默认可以读取application.properties/application.yml这两个核心配置文件 - 核心配置文件可以存在于以下四个地方: - file:./config - file:./ - classpath:./config - classpath:./ > - 在SpringBoot启动时,这四个位置的配置文件都会读取。并且是互补的关系。但是如果有某一项配置冲突,以优先级高的配置文件为准。**优先级从上往下依次降低**。 - 如果application.yml和application.properties文件同时存在,他们之间也是互补的关系,但是application.properties的优先级高于application.yml。 ## 六、外部配置文件与命令行参数 设想一个场景,项目已经开发完成并打成jar包准备上线发布了,但由于一些原因,之前的某些配置需要修改。 - 常规的做法:修改代码重新打jar包,然后再部署。这样就显得非常繁琐; - SpringBoot提供做法:1-命令行参数法(适合修改较少);2-外部配置文件(适合修改较多配置),这两种方法不需要修改原有代码重新打包,即可更改配置。 ### 5.1命令行参数 如3.3的 java -jar xxx.jar --spring.profiles.active=dev #表示使用开发环境的配置 > 如果需要输入多个命令,中间用空格隔开。 ### 5.2外部配置文件 需要修改的配置很多时,用命令行参数修改明显是不好的。这时我们可以将所有需要修改的配置放到一个外部配置文件中。然后在启动项目时,通过**--spring.config.location=D:/xxx.application**这个命令来加载外部配置文件。 ## 七、配置的优先级 上面我们提到了SpringBoot支持的很多种配置方法。如果同一个配置出现在多个地方,优先级高的配置会覆盖优先级低的配置。现在来总结一下这些常用配置方式的优先级。 - **外部配置文件>命令行参数>核心配置文件(.properties>.yml)**