@Profile 的作用
在不同的环境下使用不同的组件和配置,方便环境的动态切换
使用步骤
- 指定组件在哪个环境下生效
- 在 yml 文件中指定激活的环境
生效环境 = 激活环境/默认环境 + 包含环境(include)
环境分组
使用group来将多个环境定义成一个组,例如
spring:
profiles:
active: my-profile
# 将多个环境定义成一个组
# 鼠标放上去可以看到group的类型, 根据类型来进行格式的配置
group:
my-profile:
- test
- dev
your-profile:
- test
- prod
配置文件的 Profile 功能
以 dev 环境的配置文件为例,为 application.yml 或 application.properties 添加上后缀,构成 application-dev.yml 或 application-dev.properties。
另外,对于 spring.profiles 配置项,只能够在 application.yml(基础配置文件)中配置,在诸如 application-dev.yml 中对 profile 相关的配置不会生效。基础配置文件在任何一个环境下都会生效,类似 default,但是优先级比较低。
如果环境组中两个环境的配置冲突,那么会按顺序进行覆盖,例如上面的情况下,如果 dev 环境和 test 环境中的 server.port 配置项发生冲突,那么以后面的为主,即生效的是 dev 环境。
application-test.yml
server:
port: 8081
application-dev.yml
server:
port: 8082
测试 @Profile
pom 依赖
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.6.11</version>
</parent>
<properties>
<maven.compiler.source>8</maven.compiler.source>
<maven.compiler.target>8</maven.compiler.target>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-configuration-processor</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</dependency>
</dependencies>
Bean 对象
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
@Data
@NoArgsConstructor
@AllArgsConstructor
public class ProfileBean {
private Integer id;
private String name;
}
Configuration 配置类
import org.example.bean.ProfileBean;
import org.springframework.context.EmbeddedValueResolverAware;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Profile;
import org.springframework.core.env.Environment;
import org.springframework.util.StringValueResolver;
@Configuration
@PropertySource("classpath:my-profile.properties")
public class ProfileConfig implements EmbeddedValueResolverAware {
// TODO: 为什么这里不可以通过@Autowired来注入
private StringValueResolver valueResolver;
@Override
public void setEmbeddedValueResolver(StringValueResolver resolver) {
this.valueResolver = resolver;
}
// 通过Environment来获取环境变量和配置文件中的值
@Profile("test")
@Bean
ProfileBean profileBeanTest(Environment environment) {
String id = environment.getProperty("profiles.test.id");
String name = environment.getProperty("profiles.test.name");
System.out.println("id = " + id);
System.out.println("name = " + name);
return new ProfileBean(Integer.parseInt(id), name);
}
/**
* dev环境才注入组件
*/
@Profile("dev")
@Bean
ProfileBean profileBeanDev() {
String id = valueResolver.resolveStringValue("${profiles.dev.id}");
String name = valueResolver.resolveStringValue("${profiles.dev.name}");
return new ProfileBean(Integer.parseInt(id), name);
}
@Profile("prod")
@Bean
ProfileBean profileBeanProd() {
String id = valueResolver.resolveStringValue("${profiles.prod.id}");
String name = valueResolver.resolveStringValue("${profiles.prod.name}");
return new ProfileBean(Integer.parseInt(id), name);
}
}
SpringBootTest 测试类
import org.example.bean.ProfileBean;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.context.ApplicationContext;
@SpringBootTest
public class SpringApplicationMainTest {
@Autowired
ApplicationContext context;
@Test
public void profileTest() {
String[] names = context.getBeanNamesForType(ProfileBean.class);
for (String name : names) {
ProfileBean profileBean = context.getBean(name, ProfileBean.class);
System.out.println(profileBean);
}
}
}
properties 文件
@PropertySource 注解只对 properties 文件有效,对 yml 类型文件无效
profiles.test.id=1
profiles.test.name=test
profiles.dev.id=2
profiles.dev.name=dev
profiles.prod.id=3
profiles.prod.name=prod