Java Spring Boot 配置读取进阶篇-@ConfigurationProperties && @Value
之前我们学习了在 Spring Boot 如何读取 application.properties/application.yaml 配置文件的配置信息,在上文中我们主要是简单地实践了些简单的设置,这次我们带着同样的问题,如果配置更加复杂,我们的配置读取又应该怎么处理呢。
本文的学习主要基于 Spring Boot 自带的库来解析配置,我们只是加了个 lombok 库方便我们 @Data,这样就不用在 Bean 上写那么多代码。
话不多说,开干。
环境:
- Spring Boot:3.1.6
- JDK: 17
依赖
<dependency> <groupId>org.projectlombok</groupId> <artifactId>lombok</artifactId> <version>1.18.30</version> </dependency>
接下来的配置解析上,我们主要分是否嵌套的配置项,以及通过 @ConfigurationProperties 和 @Value 来处理。
1.简单配置
对于简单的配置,我们通常稍加代码,就解决了。
application.yaml
app: version: 1.0.0 name: my config
通过@ConfigurationProperties读取配置
package com.example.springbootconfigrddemo.config; import lombok.Data; import org.springframework.boot.context.properties.ConfigurationProperties; import org.springframework.context.annotation.Configuration; /** * 自定义配置读取 */ @Configuration @ConfigurationProperties(prefix = "app") @Data public class ConfigPropertiesLoad { private String version; private String name; }
测试读取配置
package com.example.springbootconfigrddemo.controller; import com.example.springbootconfigrddemo.config.ConfigPropertiesLoad; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RestController; import java.util.HashMap; import java.util.Map; @RestController public class ConfigPropertiesLoadController { @Autowired private ConfigPropertiesLoad cfgProperties; @GetMapping("/configProperties") public Object configProperties() { Map<String, Object> info = new HashMap<>(); info.put("name", cfgProperties.getName()); info.put("version", cfgProperties.getVersion()); return info; } }
通过@Value读取配置
package com.example.springbootconfigrddemo.config; import lombok.Data; import org.springframework.beans.factory.annotation.Value; import org.springframework.context.annotation.PropertySource; import org.springframework.stereotype.Component; @Component @PropertySource(value = "classpath:application.yaml") @Data public class ValueReadConfig { @Value("${app.version}") private String version; @Value("${app.name}") private String name; }
测试读取配置
package com.example.springbootconfigrddemo.controller; import com.example.springbootconfigrddemo.config.ValueReadConfig; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RestController; import java.util.HashMap; import java.util.Map; @RestController public class ValueReadConfigController { @Autowired private ValueReadConfig config; @GetMapping("/valueConfig") public Object valueConfig() { Map<String, Object> info = new HashMap<>(); info.put("name", config.getName()); info.put("version", config.getVersion()); return info; } }
2.带嵌套的配置
自定义的配置项多级嵌套,application.yaml:
app1: name: app1 introduction info: author: admin desc: It's a config demo
通过@ConfigurationProperties读取配置
InfoConfig.java
package com.example.springbootconfigrddemo.config; import lombok.Data; import org.springframework.boot.context.properties.ConfigurationProperties; import org.springframework.context.annotation.Configuration; @Data @Configuration @ConfigurationProperties(prefix = "app1.info") public class InfoConfig { private String author; private String desc; }
ConfigPropertiesMultiLevelLoad.java
package com.example.springbootconfigrddemo.config; import lombok.Data; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.context.properties.ConfigurationProperties; import org.springframework.context.annotation.Configuration; /** * 自定义嵌套配置读取 */ @Data @Configuration @ConfigurationProperties(prefix = "app1") public class ConfigPropertiesMultiLevelLoad { private String name; @Autowired private InfoConfig info; }
测试读取配置
package com.example.springbootconfigrddemo.controller; import com.example.springbootconfigrddemo.config.ConfigPropertiesMultiLevelLoad; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RestController; import java.util.HashMap; import java.util.Map; @RestController public class ConfigPropertiesMultiLevelController { @Autowired private ConfigPropertiesMultiLevelLoad config; @GetMapping("/configMultiLevel") public Object configMultiLevel() { Map<String, Object> ret = new HashMap<>(); Map<String, Object> info = new HashMap<>(); info.put("author", config.getInfo().getAuthor()); info.put("desc", config.getInfo().getDesc()); ret.put("name", config.getName()); ret.put("info", info); return ret; } }
通过@Value读取配置
配置读取
package com.example.springbootconfigrddemo.config; import lombok.Data; import org.springframework.beans.factory.annotation.Value; import org.springframework.context.annotation.PropertySource; import org.springframework.stereotype.Component; @Component @PropertySource(value = "classpath:application.yaml") @Data public class ValueMultiReadConfig { @Value("${app1.name}") private String name; @Value("${app1.info.author}") private String author; @Value("${app1.info.desc}") private String desc; }
测试读取配置
package com.example.springbootconfigrddemo.controller; import com.example.springbootconfigrddemo.config.ValueMultiReadConfig; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RestController; import java.util.HashMap; import java.util.Map; @RestController public class ValueMultiReadConfigController { @Autowired private ValueMultiReadConfig config; @GetMapping("/valueMultiLevel") public Object valueMultiReadConfig() { Map<String, Object> ret = new HashMap<>(); Map<String, Object> info = new HashMap<>(); info.put("author", config.getAuthor()); info.put("desc", config.getDesc()); ret.put("name", config.getName()); ret.put("info", info); return ret; } }
3.带多级嵌套的配置
如果嵌套级数更多呢,这里我们怎么处理呢,这里以 Redis配置 为例,返回 Redis的配置项参数,application.yaml:
spring: data: redis: port: 6379 host: localhost database: 1 jedis: pool: enabled: true max-active: 8 max-idle: 8 min-idle: 1
通过@ConfigurationProperties读取配置
由于是多级嵌套,我们从最内层到最外层开始编码实现,通过 @AutoWired 一层层自动装配。
Pool.java
package com.example.springbootconfigrddemo.config; import lombok.Data; import org.springframework.boot.context.properties.ConfigurationProperties; import org.springframework.context.annotation.Configuration; @Data @Configuration @ConfigurationProperties(prefix = "spring.data.redis.jedis.pool") public class Pool { private boolean enabled; private int maxActive; private int maxIdle; private int minIdle; }
Jedis.java
package com.example.springbootconfigrddemo.config; import lombok.Data; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.context.properties.ConfigurationProperties; import org.springframework.context.annotation.Configuration; @Data @Configuration @ConfigurationProperties(prefix = "spring.data.redis.jedis") public class Jedis { @Autowired Pool pool; }
Redis.java
package com.example.springbootconfigrddemo.config; import lombok.Data; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.context.properties.ConfigurationProperties; import org.springframework.context.annotation.Configuration; @Data @Configuration @ConfigurationProperties(prefix = "spring.data.redis") public class Redis { private int port; private String host; private int database; @Autowired private Jedis jedis; @Override public String toString() { return String.format("Redis{host=%s, port=%d, database=%d, jedis{enabled=%b, maxActive=%d, maxIdle=%d, minIdle=%d}}", host, port, database, jedis.pool.isEnabled(), jedis.pool.getMaxActive(), jedis.pool.getMaxIdle(), jedis.pool.getMinIdle()); } }
测试读取配置
package com.example.springbootconfigrddemo.controller; import com.example.springbootconfigrddemo.config.Redis; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RestController; @RestController public class RedisConfigController { @Autowired private Redis redis; @GetMapping("/redisConfig") public Object redisConfig() { return redis.toString(); } }
通过@Value读取配置
package com.example.springbootconfigrddemo.config; import lombok.Data; import org.springframework.beans.factory.annotation.Value; import org.springframework.boot.autoconfigure.EnableAutoConfiguration; import org.springframework.context.annotation.Configuration; @Configuration @EnableAutoConfiguration @Data public class PoolConfig { @Value("${spring.data.redis.host}") private String host; @Value("${spring.data.redis.port}") private int port; @Value("${spring.data.redis.database}") private int database; @Value("${spring.data.redis.jedis.pool.min-idle}") private int minIdle; @Value("${spring.data.redis.jedis.pool.max-active}") private int maxActive; @Value("${spring.data.redis.jedis.pool.max-idle}") private int maxIdle; @Value("${spring.data.redis.jedis.pool.enabled}") private boolean enabled; @Override public String toString() { return String.format("Pool{host=%s, port=%d, database=%d, maxIdle=%d, maxActive=%d, minIdle=%d, enabled=%b}", host, port, database, maxIdle, maxActive, minIdle, enabled); } }
测试读取配置
package com.example.springbootconfigrddemo.controller; import com.example.springbootconfigrddemo.config.PoolConfig; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RestController; @RestController public class PoolController { @Autowired private PoolConfig pool; @GetMapping("/poolConfig") public String poolConfig() { return pool.toString(); } }
总结
上面我们通过 @ConfigurationProperties 和 @Value 两种方法获取配置,前者读取配置需要注意嵌套的配置需要加一层,通过 @AutoWired 自动装配进来,后者则是通过字段全部展平赋值,如果很多级的情况下,用 @Value 实现的代码更加简洁,而使用 @ConfigurationProperties 则需要层层 AutoWired 。
总的来说,上面两种方法是我们日常开发中使用较多的配置读取的方案,有的方案是通过其他 yaml 三方库获取配置,当然也可以,方法不止一种,但从项目开发角度,怎么方便怎么简洁怎么来,毕竟快速开发业务更加重要。
参考:
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 开源Multi-agent AI智能体框架aevatar.ai,欢迎大家贡献代码
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· AI技术革命,工作效率10个最佳AI工具