原理解析-Profile 功能
# 640.原理解析-Profile 功能
为了方便多环境适配,SpringBoot 简化了 Profile 功能。
# 简介
不同测试环境下,数据库信息、Redis 信息和端口等配置可能都不同,如果要部署到不同环境,还要修改大量的配置的话,太麻烦了;
为此我们可以建立多个配置文件(格式为:application-{配置文件标识}.yml
),然后在部署的时候指定配置文件,这样就能很方便地切换环境
相关文档:4.3 小节
为了方便,我们新建一个 SpringBoot 项目,并引入 web 等依赖
# 新增 controller
新增一个 controller,并加载配置文件的值,展示到页面上:
package com.peterjxl.learnspringbootprofile.controller;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
public class HelloController {
@Value("${person.name:Peter}") // If person.name is not defined, use "Peter" as default
private String name;
@GetMapping("/")
public String sayHello() {
return "Hello " + name;
}
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
# 新增配置文件
新增 application-prod.yml:
person:
name: prod-peter
2
新增 application-test.yml:
person:
name: test-peter
2
然后就可以在 application.yaml 中,指定用哪个配置文件了,例如使用测试环境的:
spring:
profiles:
active: test
2
3
重启项目,效果:
如果改成 prod:
spring:
profiles:
active: prod
2
3
配置文件加载过程:
- 首先,默认配置文件(application.yml)一直都会被加载
- 其次,会加载指定的配置文件(例如 application-prod.yml)
- 如果两个配置文件都有同名项,那么 Profile 配置优先(application-prod.yml)
例如,application-prod.yml
配置了端口为 8000:
server:
port: 8000
person:
name: prod-peter
2
3
4
5
而默认配置文件的端口是 8080:
server:
port: 8080
spring:
profiles:
active: prod
2
3
4
5
6
那么访问的时候,以 application-prod.yml
为准:
# 在运行时指定配置
等制定好配置文件后,就可以打包,并部署到服务器上了。
但如果每次切换环境,都要重新打包也是挺麻烦的,为此我们可以在运行时指定用什么配置文件:
java -jar LearnSpringBoot-Profile-0.0.1-SNAPSHOT.jar --spring.profiles.active=test
启动的时候,也会提示是 test:
甚至可以在命令行中指定某个属性的值:
java -jar LearnSpringBoot-Profile-0.0.1-SNAPSHOT.jar --spring.profiles.active=test --person.name=wtf
效果:
# 条件装配
我们经常会给容器中注入 bean,但有时候想要生产和测试注入不同的 bean,也可以这样做。
新建一个 Color 类:
package com.peterjxl.learnspringbootprofile.bean;
public class Color {
private String name;
public Color(String name) {
this.name = name;
}
@Override
public String toString() {
return "Color [name=" + name + "]";
}
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
然后新建配置类,使用 @Profile
注解表明什么时候该注入哪个 bean:
package com.peterjxl.learnspringbootprofile.config;
import com.peterjxl.learnspringbootprofile.bean.Color;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Profile;
@Configuration
public class Myconfig {
@Bean
@Profile("prod")
public Color red() {
return new Color("red");
}
@Bean
@Profile("test")
public Color blue() {
return new Color("blue");
}
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
然后我们在页面展示下 color:
@RestController
public class HelloController {
@Autowired
Color color;
@Value("${person.name:Peter}") // If person.name is not defined, use "Peter" as default
private String name;
@GetMapping("/")
public String sayHello() {
return "Hello " + name + color;
}
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
目前我们用的是 prod 环境,因此展示了 red:
除此之外,@Profile
注解还可以用在类上
# Profile 分组
除了按环境分组,还可以根据用的技术来分组,例如 MySQL 一个配置文件,MQ 一个配置文件,Redis 一个文件....
当配置文件多了起来后,可以通过分组的方式来管理,例如 application-prod.yml,application-common.yaml 文件是一组的,那么可以这样配置:
spring.profiles.group.myprod[0]=common
spring.profiles.group.myprod[1]=prod
2
其中,myprod 是组名,可以理解为是一个数组,可以添加很多个配置文件到该数组。
然后就可以指定激活该组的配置文件:
spring.profiles.active=myprod
# 总结
默认配置文件 application.yaml,任何时候都会加载
可以新增环境配置文件,格式: application-{env}.yaml,激活指定环境的方法:
- 配置文件激活,在配置中指定 profile
- 命令行激活:在运行 jar 文件的时候指定
默认配置与环境配置同时生效,如有同名配置项,profile 配置优先
已将本文源码上传到 Gitee (opens new window) 和 GitHub (opens new window) 的分支 demo1,读者可以通过切换分支来查看本文的示例代码