概述
属性注入的两种方式:@Value 注解 和 @ConfigurationProperties 注解
二者区别 | @ConfigurationProperties | @Value |
---|---|---|
功能 | 批量注入配置文件中的属性 | 一个个指定 |
松散绑定(松散语法) | 支持 | 不支持 |
SpEL | 不支持 | 支持 |
JSR303数据校验 | 支持 | 不支持 |
复杂类型封装 | 支持 | 不支持 |
引入依赖
pom.xml 中添加如下依赖项:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-configuration-processor</artifactId>
<optional>true</optional>
</dependency>
@Value 注解
Spring中提供了@Value注解,属于属性级别的注解,注解在单条属性上,用于将配置文件中的属性值读取出来并设置到相应的属性中。
@Value 注解支持如下的属性注入:
- 字面量:字面量的类型必须与属性的类型一致
- 属性占位符:即通过 ${} 从环境变量、配置文件中获取值
- SpEL 表达式
```java
/ application.yaml 配置文件 /
user:
pInteger: 18 pDouble: 15.82 pString: 世界 lists: str1,str2,str3 #list的配置不需要加引号 maps: “{key1:12,key2:13}” #map的配置需要加引号,且key不许要加引号,value为字符串时需要单引号
/ @Value 注解 / @Component @Data public class User implements Serializable { / 字面量 / @Value(“18”) private Integer integer; // 整形
@Value("18.03")
private Double aDouble; // 浮点数
@Value("string")
private String string; // 字符串类型
/* 配置文件中获取,只支持简单数据类型 */
@Value("${user.pInteger}")
private Integer pInteger; // 从配置文件中获取整形
@Value("${user.pDouble}")
private Double pDouble; // 从配置文件中获取浮点数
@Value("${user.pString}")
private String pString; // 从配置文件中获取字符串
/* SpEL 表达式 */
@Value("#{(1+2*6-9)/2}")
private Integer sInteger; // 运算符
@Value("#{T(java.lang.Math)}")
private Class math; // 获取Math的Class实例
@Value("#{T(java.lang.Math).random() * 100}")
private Double sDouble;
@Value("#{${user.pInteger} lt 20 ? 'old':'young'}")
private String sString; // 条件运算符
@Value("#{systemProperties}")
private String[] systemPropertiesName; // 注入操作系统属性:systemProperties或者systemEnvironment
@Value("#{systemProperties['os.name']}")
private String OS;
/* @Value 注入数组、Map */
// List的配置文件为 user.lists=str1,str2,str3
// : 后面为默认值
@Value("${user.lists:default1,default2,default3}")
private List<String> lists;
// 或者使用单引号 '' 将 ${user.lists} 括起来作为整体,然后对该字符串进行拆分
@Value("#{'${user.hobby}'.split(',')}")
private List<String> lists1;
// 通过SpEL表达式对 user.maps 进行计算,赋值给Map,其中:后面为默认值
// maps: "{key1:12,key2:235}"
@Value("#{${user.maps:{key1:12,key2:13}}}")
private Map<String, Integer> maps;
}
注意事项:
1. @Value 不支持 JSR 303 校验
1. @Value 不支持
<a name="LH4Ww"></a>
#### @ConfigurationProperties(prefix = "")
@ConfigurationProperties 是类级别的注解,在需要注解的class上添加此注解,实现多属性一次性注入,然而要求配置文件中的属性名和 class 的属性名一致,是通过Setter注入的,所以必须实现 set 方法。该注解默认从全局文件,即 application.yaml 或 application.properties 中获取属性,如果需要自定义属性,需要和 @PropertySource 注解连用。其有如下优势:<br />1、支持松散绑定:松散绑定的意思是一个属性可以在配置文件中有多个属性名,即属性 username 支持在配置文件中写成 USERNAME、UserName、user-name 等。<br />2、支持 JSR 303 数据校验:即在属性进行赋值时会检查属性上的校验,如果校验不成功则会抛出异常
```java
@Component
@Validated
@Data
@ConfigurationProperties(prefix = "student")
@PropertySource("classpath:student.properties")
public class Student {
@Length(min = 6,max = 16,message = "name长度不符合要求")
private String name;
@DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
private LocalDateTime localDateTime;
}
3、支持复杂类型封装:复杂类型指的是在对象、list、map等属性中,是无法使用 @Value 获取到值
4、支持 @DateTimeFormat 注解定义时间格式
@Value 和 @ConfigurationProperties 选用
- 只需要在某个业务逻辑中获取一下配置文件的某项值,使用 @Value 注解
- 专门编写一个 javaBean 和配置文件进行映射,使用 @ConfigurationProperties 注解
@PropertySource 和 @ImportResource
通过 @PropertySource 注解进行配置文件的引入,该注解存在如下参数:
- value:必须,设置需要加载的属性文件,可以一次性加载多个,当一次性加载的文件存在相同的 key 时,则最后一个加载的文件中的 key 生效,如
value={"classpath:/config/XX1.properties","classpath:/config/XX2.properties"}
- name:必须全局唯一,不设置则会根据规则生成默认值
- 默认设置规则:根据 value 值查找到最终封装的 Resource 子类,然后调用具体的 Resource 子类实例对象中的 getDescription 方法,getDescription 方法的返回值为最终的 name 值。
- value 值为 classpath:开头时,会使用 Resource 的子类 ClassPathResource。如果是 file 开头的,则最终使用的类是 FileSystemResource。
- ignoreResourceNotFound:含义是当指定的配置文件不存在是否报错,默认是 false ;实际项目开发中,最好设置 ignoreResourceNotFound 为 false。
- encoding:字符集,一般
encoding = "UTF-8"
@ImportResource(locations = {“classpath:xx.xml”}):导入 Spring 的配置文件,让配置文件生效。Spring Boot 中当我们需要导入自定义的Spring的配置文件 xx.xml 时,可以在配置类上使用该注解进行加载。