1.前言
上一篇 介绍了 Spring Boot 的入门,在一般情况下,我们不需要做太多的配置就能够让 Spring Boot 正常运行。因为其使用“习惯优于配置”(项目中存在大量的配置,此外还内置了一个习惯性的配置,让你无需手动进行配置)的理念可以让我们的项目快速运行起来。 但是,我们还是需要有项目的,或者自己的属性配置。
2.进击
2.1.自定义属性
当我们创建完一个 Spring Boot 项目的时候,会发现,系统默认给我们在项目的 src/main/java/resources 目录下创建了一个application.properties。这就是我们这章要讲的文件。
因为 YML 是 Spring Boot 的一个重要特性,所以,这里我会将 application.properties 修改为 application.yml 。但是两种文件格式 Spring Boot 都支持,只是语法上,数据结构上有所不同。
2.1.1.自定义一组属性
在 application.yml 中自定义一组属性及其值:
server:
port: 8000
wei:
name_cn: 测试
2.1.2.读取配置(通过 @Value("${属性名}") 来读取配置文件的值)
自定义属性配置好后,在需要读取的地方直接使用注解 @Value("${属性名}") 进行属性绑定和读取。
package com.wei.controller.demo;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
/**
* 注解@RestController,相当于@Controller和@ResponseBody两个注解的结合,使用这个注解的类里面的方法都以json格式输出
*/
@RestController
public class DemoController {
@Value("${wei.name_cn}")
private String name_cn;
@Value("${server.port}")
private String port;
@RequestMapping(value = "/demo/hi")
public String getDemoHi() {
String result = "Hello, Spring Boot! 我是" + name_cn + ",端口:" + port;
System.out.println(result);
return result;
}
}
运行程序启动类,浏览器访问URL:http://localhost:8000/demo/hi
我们可以看到浏览器显示:
Hello, Spring Boot! 我是测试,端口:8000
2.2.自定义配置文件
有时候我们并不希望把所有配置项都放在 application.yml 里面,这时候我们可以另外自定义一个,比如 application-user.yml。
有时候我们有很多配置属性,这时我们会把这些属性作为字段来创建一个Java Bean,并将属性值赋给他们。
2.2.1.自定义一组属性
新建自定义配置文件 application-user.yml ,并定义以下属性:
wei:
name_cn: 测试
name_en: SpringBoot-Tester
age: ${random.int[1,300]}
user_id: ${random.int}
desc: Dear All, name:${name_en}, user_id:${user_id}, age:${age}
- 属性间引用:
配置文件中的各个属性之间也可以直接引用来使用,比如属性desc
- 随机值配置:
配置文件中的 ${random} 可以用来生成各种不同类型的随机值,简化代码生成的麻烦,比如生成 int 值,long 值,或者 string 字符串。
2.2.2.读取配置(将配置文件的属性赋给实体类来读取配置文件的值 )
新建一个Javabean类,其属性与 application-user.yml 中的属性相互对应。当然,也可以使用 @Value("${desc}") 注解一个别名。如下:
package com.wei.model;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.PropertySource;
import org.springframework.stereotype.Component;
/**
* 注解@ConfigurationProperties,并加上它的prrfix,来指明使用哪个配置
* 注解@PropertySource,引入自定义配置文件
*/
@Component
@Configuration
@PropertySource(value = "classpath:application-user.yml")
@ConfigurationProperties(prefix = "wei")
public class DemoUserBean {
@Value("${name_cn}")
private String nameCn;
@Value("${age}")
private int age;
@Value("${user_id}")
private int userId;
@Value("${desc}")
private String description;
public String getNameCn() {
return nameCn;
}
public void setNameCn(String nameCn) {
this.nameCn = nameCn;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public int getUserId() {
return userId;
}
public void setUserId(int userId) {
this.userId = userId;
}
public String getDescription() {
return description;
}
public void setDescription(String description) {
this.description = description;
}
}
这里需要加注解@ConfigurationProperties,并加上它的prrfix,来指明使用哪个配置。加注解@PropertySource,来引入我们自定义的配置文件 application-user.yml。
2.2.3.添加核心依赖
pom.xml 依赖中添加一个核心依赖开启注解@ConfigurationProperties
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-configuration-processor</artifactId>
<optional>true</optional>
</dependency>
官方对 spring-boot-configuration-processor 的说明:
通过使用spring-boot-configuration-processor jar, 你可以从被@ConfigurationProperties注解的节点轻松的产生自己的配置元数据文件。该jar包含一个在你的项目编译时会被调用的Java注解处理器。想要使用该处理器,你只需简单添加spring-boot-configuration-processor依赖。
2.2.4.在Controller类中引入ConfigBean
注解@EnableConfigurationProperties,指明要加载哪个bean。否则 @Autowired DemoUserBean 不能进行自动装载。
package com.wei.controller.demo;
import com.wei.model.DemoUserBean;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
/**
* 注解@RestController,相当于@Controller和@ResponseBody两个注解的结合,使用这个注解的类里面的方法都以json格式输出
* 注解@EnableConfigurationProperties,指明要加载哪个bean
*/
@RestController
@EnableConfigurationProperties({DemoUserBean.class})
public class DemoUserController {
@Autowired
private DemoUserBean demoUserBean;
@RequestMapping(value = "/demo/user/hi")
public String getDemoHi() {
String result = "Hello, Spring Boot! 我是" + demoUserBean.getNameCn() + ",我的简介:" + demoUserBean.getDescription();
System.out.println(result);
return result;
}
}
好了,现在我们重启程序启动类,看看配置文件信息是不是正常被注入到 Java Bean,并读取到了。
访问URL:http://localhost:8000/demo/user/hi
浏览器会打印:
Hello, Spring Boot! 我是测试,我的简介:Dear All, name:SpringBoot-Tester, user_id:813655093, age:214
大功告成。其实,如果上面所说的 application-user.yml 文件里面的配置都是在 application.yml 文件里的话,那么就不需要上面 2.1.2.读取配置 DemoUserBean 里面的 @PropertySource 注解,然后重复 2.1 的操作,同样可以读取到配置属性。
2.3.多环境配置
现实的开发过程中,我们需要不同的配置环境。Spring Boot 为我们提供了此配置功能。格式为 application-{profile}.properties 或者 application-{profile}.yml,其中{profile}对应你的环境标识,比如:
- 开发环境:application-dev.yml
- 测试环境:application-test.yml
- 生产环境:application-prod.yml
开发环境 application-dev.yml 配置如下:
server:
port: 8002
servlet:
context-path: /springboot-dev
测试环境 application-test.yml 配置如下:
server:
port: 8004
servlet:
context-path: /springboot-test
我们只需要在 application.yml 中使用 spring.profiles.active 来设置对应的环境,就能切换不同的环境,也就是{profile}部分(上面定义的dev、test、prod):
server:
port: 8000
spring:
profiles:
active: test
wei:
name_cn: 测试
age: ${random.int[1,300]}
user_id: ${random.int}
desc: Dear All, name:${wei.name_cn}, user_id:${wei.user_id}, age:${wei.age}
怎么验证呢?
我们再次重启程序启动类,没错,细心的你,应该也已经发现了,控制台的日志输出告诉我们,其实程序启动时已经把默认的端口切换到了你在 application.yml 中指定的环境 test 所对应的端口 8004,并且访问所有的路由时需要加上 /springboot-test 根才能访问到。
原来的URL http://localhost:8000/demo/user/hi,是不是已经无法访问?
再来试试 http://localhost:8004/springboot-test/demo/user/hi,如你所见,浏览器正常打印了:
Hello, Spring Boot! 我是测试,我的简介:Dear All, name:SpringBoot-Tester, user_id:556944052, age:205
3.总结
好了,至此,我们已经掌握了 Spring Boot 配置文件的:
- 自定义属性
- 自定义配置文件
- 属性(参数)间的引用
- 随机值配置
- 多环境配置
最后,重点再讲一下配置优先原则,Spring Boot 的配置文件是按照自上而下的顺序来解析的,也就是说,同样的文件,或者同样的Key,顺位最上的将会是最终有效的。
比如:如果你在resources目录下同时有 application.properties 和 application.yml,那么 application.properties 里面的属性就会覆盖application.yml,因为相同优先级位置,文件 application.properties 在顺位最上。
比如:src/main/resources/config 目录下 application.properties 配置文件将会覆盖 src/main/resources 目录下 application.properties 中相同的属性。
源码:https://github.com/itanping/wei-springboot
Spring Boot 进击:SpringBoot进击 | 一浅出:Spring Boot简单快速入门
Spring Cloud 进击:SpringCloud进击 | 一浅出:服务注册与发现(Eureka)【Finchley版本】