<dependency>
<groupId>org.springframework.bootgroupId>
<artifactId>spring-boot-configuration-processorartifactId>
<scope>providedscope>
dependency>
<dependency>
<groupId>org.projectlombokgroupId>
<artifactId>lombokartifactId>
dependency>
import java.time.LocalDateTime;
import java.util.Date;
import java.util.List;
import java.util.Map;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;
import lombok.*;
@Component // 一定要注入容器我们YAML才能解析
// 因为只有spring 组件才能使用下面的注解
// 要制定前缀,我们字段就是我们的YAML的属性
@ConfigurationProperties(prefix = "person")
@Getter
@Setter
@ToString
public class Person {
private String userName;
private String address;
private Integer age;
private Date birth;
// private LocalDateTime birth;
private boolean boss;
private Map<String, String> map;
private List<String> hobbys;
private Dept dept;
private Map<String, Dept> allDepts;
}
@Data
@Component
public class Dept {
private Integer deptId;
private String deptName;
}
@RestController
public class MyController {
@Autowired
private Person person;
@Value("${person.user-name}")
private String userName;
@GetMapping("")
public Person test() {
System.out.println(userName);
return person;
}
}
person:
userName: 名字 # userName = user-name
address: 湖南长沙
age: 18
birth: 2023/07/24 14:12:12 # 默认,标准格式
# birth: 2023-07-24 00:00:00 # localDateTime
boss: true
#map: {k1:v1, k2:v2, k3:v3}
map :
k1: v1
k2: v2
k3: v3
#hobbys:[篮球,足球,羽毛球]
hobbys : # 数组类型
- 篮球
- 足球
- 羽毛球
dept:
deptId: 1
deptName: 行政部
all-depts:
k1: {deptId: 1,deptName: 行政部}
k2:
deptId: 2
deptName: 财务部
仔细看YAML中的格式即可,只有两点注意
@ConfigurationProperties(prefix = "person")
注解。这个注解也有一个前提,必须是Spring的组件所以我们还需要一个注解:@Component
。综上,我们如果需要解析特定的对象时,首先他需要在我们的容器中(一个Bean对象),其次需要指定前缀(也就是相当于类名,实例化后的对象名),这样我们在使用的时候才可以直接@Autowired
这个实例化对象,同时获取到对应的属性。补充:
@ConfigurationProperties,该注解属于 Spring Boot 的核心依赖之一,因此不需要额外的依赖来使用它。在 Spring Boot 项目中,只需要引入了 Spring Boot 的核心依赖(例如 spring-boot-starter)
使用
@Value()
直接获取
@Value("${person.user-name}") // YAML中的属性名,全名
private String userName;
补充:
@Value使用SpEL(Spring表达式语言)来实现更复杂的值注入。在SpEL中,#{} 和 ${} 都是表达式的占位符,但它们的使用场景和功能有所不同。
@Value("${my.property}")
private String myProperty;
在这个例子中,my.property 是应用程序配置文件(比如application.properties或application.yml)中定义的一个属性。在运行时,${my.property} 会被配置文件中的实际值所替换。
2. #{}:这是一个更复杂的表达式占位符,允许你执行更复杂的SpEL表达式。这些表达式可以包含方法调用、算术运算、字符串操作等等。例如:
@Value("#{ T(java.util.Arrays).asList('a', 'b', 'c') }")
private List<String> myList;
在这个例子中,T(java.util.Arrays).asList(‘a’, ‘b’, ‘c’) 是一个SpEL表达式,它调用了java.util.Arrays 的 asList 方法,并将字符串 ‘a’, ‘b’, ‘c’ 转换为一个列表。在运行时,这个表达式会被执行,并且返回的结果会被注入到 myList 变量中。
注意:
#{} 表达式的执行是在应用启动时进行的,而不是在每次需要使用这个值的时候。
${} 表达式的值是从配置文件中读取的,是在应用启动后每次需要使用这个值的时候读取的。
因此,如果你的SpEL表达式执行起来比较耗时,或者它的结果不会改变,那么使用 #{} 是更好的选择。否则,如果你需要动态地改变一个值(比如根据其他bean的状态),那么使用 ${} 是更好的选择。
特殊技巧:
@Value 处理 List/arr ,前提他们在定义的时候是[x,t,…]或者 x,y,t…这样定义的。
我们直接获取他们的值,然后把他们当String处理了,用split做切分即可。
@Value("#{ T(java.util.Arrays).asList('a', 'b', 'c') }")
private List<String> myList;
数组、集合、自定义类对象,需要创建一个可以接受他们的Bean对象,然后指定YAML对他们值做接收的前缀,然后通过这个Bean对象我们获取,这个对象下他们所具有具体值。