多环境配置与数据绑定
# 多环境配置与数据绑定
# 多环境配置
我们在开发完一个需求之后,通常会在各个环境进行联调测试;各个环境的yml配置会有不同,如常见的端口配置,数据库信息配置等。那如何实现这个需求呢?
Spring Boot 支持通过 application-{profile}.properties
(或者application-{profile}.yaml
)文件来管理不同环境的配置。例如:
application-dev.properties
:开发环境配置application-test.properties
:测试环境配置application-prod.properties
:生产环境配置
比如,现在我们创建了一个application-prod.yml文件,代表生成环境配置
spring:
profiles:
active: prod
server:
port: 8080
2
3
4
5
6
接着,在 application.properties
文件中指定默认的配置文件:
spring.profiles.active=prod
到此,我们就实现了指定环境运行项目。
# 命令方式启动
java -jar your-app.jar --spring.profiles.active=prod
项目打包时,如果有多环境配置文件会一起打包进去,启动项目时,我们可以通过命令来覆盖主配置文件配置环境。
比如说,application.properties
文件中环境为dev,我们通过命令指定为prod
,那它启动时,就会是prod
.
# 数据绑定
在 Spring Boot 中,@Value
注解用于从配置文件中注入属性值到字段、方法或构造函数参数中。@Value
是一个非常有用的注解,可以帮助你将外部配置文件中的值注入到你的应用程序中。
以下是它的三种不同方式:
- 注入简单属性:
- 从配置文件(如
application.properties
或application.yml
)中注入简单的属性值。 - 例如,从
application.properties
中读取server.port
并注入到字段中。
- 从配置文件(如
- 注入表达式:
- 支持 SpEL(Spring Expression Language)表达式,可以在注入时进行简单的计算和条件判断。
- 例如,从配置文件中读取多个属性并进行拼接。
- 注入默认值:
- 可以在注入时提供默认值,以防配置文件中没有定义该属性。
- 例如,如果
application.properties
中没有定义server.port
,可以提供一个默认值。
一个简单的例子,假设你有以下 application.properties
文件:
server.port=8080
app.name=MyApp
app.description=This is my application
2
3
接着在对应的类上,使用@Value注解,然后使用对应表达式,这样就完成了值的赋予。
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
@Component
public class AppConfig {
@Value("${server.port}")
private int serverPort;
@Value("${app.name}")
private String appName;
@Value("${app.description}")
private String appDescription;
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
以后再调用AppConfig.serverPort的值,就会发现它是“8080”。这就是简单注入。
@Value("#{${app.name} + ' - ' + ${app.description}}")
private String appInfo;
// 以上是 表达式注入
2
3
还有默认值的注入。如果配置文件中没有定义对应属性值,比如 property_name
,则使用 default_value
。
@Value("${server.port:8081}")
private int serverPort;
2
@Value("${server.port:8081}")
注解中的 :8081
部分指定了一个默认值。这意味着如果配置文件中没有定义 server.port
属性,那么 serverPort
字段将被赋值为 8081
。
# 前置条件
在 Spring Boot 中,@Value
注解用于从配置文件中注入属性值,但它的工作机制依赖于 Spring 的依赖注入(DI)容器。因此,如果你想使用 @Value
注解来注入属性值,通常需要将类加入到 Spring 的 IoC 容器中。
# 高效的方式
除了使用@Value还有另一种更高效的方式,那就是——@ConfigurationProperties。
@ConfigurationProperties
是 Spring Boot 中用于将配置文件中的属性批量绑定到 Java 对象的核心注解。它简化了配置管理,避免了逐字段使用 @Value
的繁琐操作,是 Spring Boot 外部化配置和类型安全配置的推荐方式。
# 作用
批量绑定配置
将 application.yml
或 application.properties
中的属性(如数据库连接、第三方服务参数)映射到 Java 对象的字段。
类型安全
自动将配置值转换为目标类型(如 String
→ Integer
、List
、Map
等),避免手动转换。
支持复杂结构 可绑定嵌套对象、列表、集合等复杂数据结构。
# 基本用法
以下是一个例子:
@ConfigurationProperties(prefix = "app") // 绑定以 "app" 开头的配置
@Component // 或结合 @Configuration 使用
@Data // Lombok 生成 Getter/Setter(必须提供字段访问方法)
public class AppConfig {
private String name;
private int version;
private List<String> servers;
private Database database; // 嵌套对象
@Data
public static class Database {
private String url;
private String username;
private String password;
}
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
同样的,绑定的类,也需要将其加入到 Spring 的 IoC 容器中。
或者你可以在 Spring Boot 主类或配置类上启用:
@SpringBootApplication
@EnableConfigurationProperties(AppConfig.class) // 显式启用
public class Application { ... }
2
3
以下是对应的配置文件:
app:
name: "MyApplication"
version: 1
servers:
- "server1"
- "server2"
database:
url: "jdbc:mysql://localhost:3306/db"
username: "root"
password: "123456"
2
3
4
5
6
7
8
9
10
注入后,如何使用呢?很简单,直接输入对应类,如何调用类即可。以下是一个实例Java类。
@Service
public class MyService {
@Autowired
private AppConfig appConfig;
public void printConfig() {
System.out.println(appConfig.getName()); // 输出 "MyApplication"
System.out.println(appConfig.getDatabase().getUrl()); // 输出数据库 URL
}
}
2
3
4
5
6
7
8
9
10
# 高级用法跟注意事项
它同样支持参数校验等,可以结合 @Validated
注解一起使用,对属性进行校验。比如,你可以使用 @NotNull
, @Size(min=5)
等注解来约束属性的有效性。
@ConfigurationProperties(prefix = "app")
@Validated
public class AppConfig {
@NotBlank
private String name;
@Min(1)
private int version;
}
2
3
4
5
6
7
8
9
结合 @Validated
和 JSR-303 注解(如 @NotBlank
、@Min
)验证配置合法性.
# 总结
特性 | @ConfigurationProperties | @Value |
---|---|---|
批量绑定 | ✅ 支持 | ❌ 需逐个字段绑定 |
类型安全 | ✅ 自动类型转换 | ❌ 需手动转换(如 SpEL 表达式) |
复杂结构支持 | ✅ 支持嵌套对象、集合 | ❌ 仅支持简单类型 |
松散绑定 | ✅ 支持属性名灵活匹配 | ❌ 严格匹配属性名 |
适用场景 | 结构化配置(如数据库、第三方服务) | 单个简单配置项 |