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 三方库获取配置,当然也可以,方法不止一种,但从项目开发角度,怎么方便怎么简洁怎么来,毕竟快速开发业务更加重要。

参考:

posted on   进击的davis  阅读(486)  评论(0编辑  收藏  举报

相关博文:
阅读排行:
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 开源Multi-agent AI智能体框架aevatar.ai,欢迎大家贡献代码
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· AI技术革命,工作效率10个最佳AI工具

导航

< 2025年3月 >
23 24 25 26 27 28 1
2 3 4 5 6 7 8
9 10 11 12 13 14 15
16 17 18 19 20 21 22
23 24 25 26 27 28 29
30 31 1 2 3 4 5
点击右上角即可分享
微信分享提示