在 spring boot 中,使用 @configurationproperties 或 @value 可以将配置文件(yaml / properties)中的集合类型数据绑定到 java 的 list、map、array 上。这是管理复杂配置结构的核心技能。
一、准备工作
第一步:引入依赖
<dependency>
<groupid>org.springframework.boot</groupid>
<artifactid>spring-boot-configuration-processor</artifactid>
<optional>true</optional>
</dependency>此依赖非必须,但推荐引入,便于 ide 提供配置提示。
第二步:启用配置绑定
在 spring boot 中,使用 @configurationproperties 的类需要被 spring 管理。常用方式:
@component
@configurationproperties(prefix = "app")
public class appproperties {
// 字段及 getter/setter
}
或在配置类上使用 @enableconfigurationproperties 指定要绑定的类。
二、绑定 list
2.1 绑定简单字符串 list
yaml 配置:
app:
servers:
- server1.example.com
- server2.example.com
- server3.example.comjava 代码:
@component
@configurationproperties(prefix = "app")
@getter
@setter
public class appproperties {
private list<string> servers;
}
等效的 properties 写法:
app.servers[0]=server1.example.com app.servers[1]=server2.example.com app.servers[2]=server3.example.com
2.2 绑定对象 list
yaml 配置:
app:
users:
- name: zhangsan
age: 25
email: zhangsan@example.com
- name: lisi
age: 30
email: lisi@example.comjava 代码:
@component
@configurationproperties(prefix = "app")
@getter
@setter
public class appproperties {
private list<user> users;
@getter
@setter
public static class user {
private string name;
private int age;
private string email;
}
}
2.3 绑定基本类型 list(int、long、boolean)
yaml 配置:
app: ports: [8080, 8081, 8082] enabled-features: [true, false, true] ids: [1001, 1002, 1003]
java 代码:
@component
@configurationproperties(prefix = "app")
@getter
@setter
public class appproperties {
private list<integer> ports;
private list<boolean> enabledfeatures;
private list<long> ids;
}
2.4 使用 @value 绑定 list(逗号分隔)
yaml 配置:
app: servers: server1,server2,server3
java 代码:
@value("${app.servers}")
private list<string> servers;
注意:@value 绑定的 list 默认按逗号拆分。如果值中包含逗号,需要使用 spel 表达式处理。
三、绑定 map
3.1 绑定简单 map(string 到 string)
yaml 配置:
app:
configs:
timeout: 30
retry: 3
debug: truejava 代码:
@component
@configurationproperties(prefix = "app")
@getter
@setter
public class appproperties {
private map<string, string> configs;
}
3.2 绑定复杂 map(string 到 object)
yaml 配置:
app:
datasources:
primary:
url: jdbc:mysql://localhost:3306/main
username: root
password: 123456
secondary:
url: jdbc:mysql://localhost:3306/backup
username: backup
password: 654321java 代码:
@component
@configurationproperties(prefix = "app")
@getter
@setter
public class appproperties {
private map<string, datasourceconfig> datasources;
@getter
@setter
public static class datasourceconfig {
private string url;
private string username;
private string password;
}
}
3.3 使用 @value 绑定 map(需要 spel)
@value("#{${app.configs}}")
private map<string, string> configs;
app.configs 在 yaml 中必须写成内联格式:
app:
configs: {timeout: 30, retry: 3, debug: true}或使用 properties:
app.configs={timeout:30, retry:3, debug:true}四、绑定 array
数组的绑定方式与 list 完全相同。
yaml 配置:
app:
servers:
- server1
- server2
- server3
ports: [8080, 8081, 8082]java 代码:
@component
@configurationproperties(prefix = "app")
@getter
@setter
public class appproperties {
private string[] servers;
private int[] ports;
}
五、绑定 set
set 与 list 绑定方式一致,但 set 会自动去重。
private set<string> servers;
六、嵌套集合
6.1 list 嵌套 map
yaml 配置:
app:
databases:
- type: mysql
config:
url: jdbc:mysql://localhost:3306/db1
pool-size: 10
- type: postgresql
config:
url: jdbc:postgresql://localhost:5432/db2
pool-size: 20java 代码:
@component
@configurationproperties(prefix = "app")
@getter
@setter
public class appproperties {
private list<databaseconfig> databases;
@getter
@setter
public static class databaseconfig {
private string type;
private map<string, object> config;
}
}
6.2 map 嵌套 list
yaml 配置:
app:
clusters:
cluster-a:
nodes:
- node1
- node2
cluster-b:
nodes:
- node3
- node4java 代码:
@component
@configurationproperties(prefix = "app")
@getter
@setter
public class appproperties {
private map<string, cluster> clusters;
@getter
@setter
public static class cluster {
private list<string> nodes;
}
}
七、默认值与占位符
7.1 设置默认值
@value("${app.servers:default-server}")
private list<string> servers;
但 @value 的默认值不支持复杂类型。使用 @configurationproperties 时在字段上直接设置默认值:
private list<string> servers = arrays.aslist("default-server");
7.2 使用占位符引用其他配置
app:
default-server: server1
servers: ${app.default-server},server2,server3八、注意事项与最佳实践
1. 避免泛型擦除问题
@configurationproperties 通过 setter 方法的参数类型或字段类型推断泛型,通常能正常工作。如果遇到问题,可以使用 @nestedconfigurationproperty 注解给容器提示:
@nestedconfigurationproperty private list<user> users;
2. 确保有 getter 和 setter
spring boot 通过 setter 方法注入值,字段本身可以是 private,但必须有对应的 setter。使用 lombok 的 @data 或 @getter @setter 可以简化。
3. 注意 yaml 缩进
yaml 的缩进代表层级,一个空格错误可能导致绑定失败。
# 正确
users:
- name: zhangsan
age: 25
# 错误(缩进不对齐)
users:
- name: zhangsan
age: 254. 使用 @validated 校验集合元素
@component
@configurationproperties(prefix = "app")
@validated
@getter
@setter
public class appproperties {
@notempty
private list<@notblank string> servers;
}
5. 何时用 @configurationproperties,何时用 @value
| 场景 | 推荐方式 |
|---|---|
| 少量简单配置 | @value |
| 一组相关配置 | @configurationproperties |
| 复杂嵌套结构 | @configurationproperties |
| 需要 spel 动态计算 | @value |
| 需要校验 | @configurationproperties + @validated |
九、完整示例
application.yml:
app:
name: myapp
servers:
- server1
- server2
- server3
ports: [8080, 8081, 8082]
features:
cache: true
logging: false
audit: true
users:
- name: zhangsan
age: 25
- name: lisi
age: 30
datasources:
primary:
url: jdbc:mysql://localhost:3306/main
username: root
secondary:
url: jdbc:mysql://localhost:3306/backup
username: backup
clusters:
cluster-a:
nodes: [node1, node2]
cluster-b:
nodes: [node3, node4]java 代码:
@component
@configurationproperties(prefix = "app")
@validated
@data
public class appproperties {
@notblank
private string name;
private list<string> servers;
private int[] ports;
private map<string, boolean> features;
@notempty
private list<user> users;
private map<string, datasourceconfig> datasources;
private map<string, cluster> clusters;
@data
public static class user {
@notblank
private string name;
@min(1)
@max(120)
private int age;
}
@data
public static class datasourceconfig {
private string url;
private string username;
}
@data
public static class cluster {
private list<string> nodes;
}
}
测试:
@springboottest
class apppropertiestest {
@autowired
private appproperties appproperties;
@test
void testproperties() {
system.out.println(appproperties.getservers()); // [server1, server2, server3]
system.out.println(appproperties.getusers()); // [user(name=zhangsan, age=25), ...]
system.out.println(appproperties.getdatasources().get("primary").geturl());
system.out.println(appproperties.getclusters().get("cluster-a").getnodes());
}
}
十、总结
| 集合类型 | 使用场景 | 推荐方式 |
|---|---|---|
list | 有序的重复元素列表(如服务器列表) | @configurationproperties |
set | 无需去重的集合(如唯一 id 列表) | @configurationproperties |
array | 与 list 类似,但不可变 | @configurationproperties |
map | 键值对映射(如不同环境的配置) | @configurationproperties |
list<object> | 对象列表(如用户列表) | @configurationproperties |
map<string, object> | 复杂键值对(如多数据源配置) | @configurationproperties |
在 spring boot 中,绑定集合类型配置的最佳实践是:优先使用 @configurationproperties,它支持松散绑定、类型安全、校验和复杂嵌套结构。@value 更适合简单的单个配置值。掌握集合类型的绑定,能够让你灵活地管理各种复杂配置,使代码更清晰、更可维护。
以上就是springboot将配置信息绑定到list、map、array的方法详解的详细内容,更多关于springboot配置信息绑定的资料请关注代码网其它相关文章!
发表评论