应用场景
在开发中,我们经常需要把一些随时可能变化的属性配置到配置文件中,这样耦合性低,方便维护。Spring Boot在这方面为我们提供了很大的便捷,我们可以很轻易的将properties
、yml
、yaml
中配置的属性绑定到JAVA实体类上。
具体实施
*注意事项
- 您需要保证您需要绑定参数的这个类是被Spring IOC容器所管理的
- 您这个需要绑定参数的类至少需要具有set方法,不然无法绑定(但不会报错,下面演示中使用的lombok提供get、set方法等)
- 您在使用这个类的时候也应该是遵循Spring 依赖注入的规范
代码解释:请看下面的代码:我创建了一个Configuration
类(我使用了Lombok提供get、set方法等),他有一个静态内部类:Properties
,这个内部类我用来作为“配置类出现”,为它绑定属性。所以我用@Component
注解将它交给IOC容器管理,又由于我的Configuration
类需要注入Properties
“配置类”,所以我也将Configuration
类交给了IOC容器管理,在Configuration
中使用@Resource
注解注入了Properties
,而print
方法作为测试方法,我为它加了@PostConstruct
注解(在依注入完成之后自动执行,方便查看测试结果)
package com.scfenzhi.config;
import lombok.Data;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;
import javax.annotation.PostConstruct;
import javax.annotation.Resource;
/**
* @Author: Yi Dai
* @Email: 484201132@qq.com
* @CreateTime: 2022-01-15 15:51
* @Company: Sichuan Fenzhi International Trade Co., LTD
* @Description:
*/
@Component
public class Configuration {
@Resource
private Properties properties;
@Data
@Component
@ConfigurationProperties(prefix = "configuration.properties")
private static class Properties {
}
@PostConstruct
public void print() {
System.out.println(properties);
}
}
基本数据类型及字符串类型
Java代码
package com.scfenzhi.config;
import lombok.Data;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;
import javax.annotation.PostConstruct;
import javax.annotation.Resource;
/**
* @Author: DaiYi
* @Email: 484201132@qq.com
* @CreateTime: 2022-01-15 15:51
* @Company: Sichuan Fenzhi International Trade Co., LTD
* @Description:
*/
@Component
public class Configuration {
@Resource
private Properties properties;
@Data
@Component
@ConfigurationProperties(prefix = "configuration.properties")
private static class Properties {
private byte byteType;
private short shortType;
private int intType;
private long longType;
private float floatType;
private double doubleType;
private boolean booleanType;
private char chatType;
private String str1;
private String str2;
private String str3;
}
@PostConstruct
public void print() {
System.out.println(properties);
}
}
yaml代码
configuration:
properties:
byte-type: 1
short-type: 1
int-type: 1
long-type: 1
float-type: 1.0F
double-type: 1.0D
boolean-type: true
chat-type: 97
str1: haha
str2: 'heihei'
str3: "xixixi"
输出结果
Configuration.Properties(byteType=1, shortType=1, intType=1, longType=1, floatType=1.0, doubleType=1.0, booleanType=true, chatType=a, str1=haha, str2=heihei, str3=xixixi)
特别注意:
- 绑定char类型时,您可以选择使用字符表码表中的数值来代替字符(比如我上面的
97
就表示字母a
),当然,您也可以使用字面量表示,如chat-type: a
,值您也可以选择用单引号或者双引号包裹起来。这并不会报错。 - 绑定String类型时,您可以选择不用引号或者使用单引号,甚至双引号也可以,都不会报错。在有特殊字符的情况下,使用引号可能是个不错的选择。
- 绑定
boolean
类型参数时,您不仅可以使用true
、false
来表示。您还可以用on
或者off
表示(on=true,off=false) - 绑定
float
类型或者double
类型时,您可以选择在值的后面加一个标识符标识类型,如1.0f
表示这是float
类型,1.0D
表示这是double
类型,大小写均可。但是比较坑的是,long
类型是不能加L
或者l
标识符的,这会报错:
Failed to bind properties under ‘configuration.properties.long-type’ to long:
Property: configuration.properties.long-type
Value: 1L
Origin: class path resource [application.yml] - 89:16
Reason: failed to convert java.lang.String to long (caused by java.lang.NumberFormatException: For input string: “1L”)
对象类型(自定义对象)
Java代码
package com.scfenzhi.config;
import lombok.Data;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;
import javax.annotation.PostConstruct;
import javax.annotation.Resource;
/**
* @Author: Yi Dai
* @Email: 484201132@qq.com
* @CreateTime: 2022-01-15 15:51
* @Company: Sichuan Fenzhi International Trade Co., LTD
* @Description:
*/
@Component
public class Configuration {
@Resource
private Properties properties;
@Data
@Component
@ConfigurationProperties(prefix = "configuration.properties")
private static class Properties {
private User user;
}
@Data
private static class User {
private int id;
private String username;
private boolean gender;
}
@PostConstruct
public void print() {
System.out.println(properties);
}
}
yaml代码(写法一)
configuration:
properties:
user: { id: 1001,username: Yi Dai,gender: false }
yaml代码(写法二)
configuration:
properties:
user:
id: 1001
username: Yi Dai
gender: on
输出结果
两种写法输出结果一致
Configuration.Properties(user=Configuration.User(id=1001, username=Yi Dai, gender=true))
数组类型
Java代码
package com.scfenzhi.config;
import lombok.Data;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;
import javax.annotation.PostConstruct;
import javax.annotation.Resource;
/**
* @Author: Yi Dai
* @Email: 484201132@qq.com
* @CreateTime: 2022-01-15 15:51
* @Company: Sichuan Fenzhi International Trade Co., LTD
* @Description:
*/
@Component
public class Configuration {
@Resource
private Properties properties;
@Data
@Component
@ConfigurationProperties(prefix = "configuration.properties")
private static class Properties {
private String[] stringArray;
private User[] userArray;
}
@Data
private static class User {
private int id;
private String username;
private boolean gender;
}
@PostConstruct
public void print() {
System.out.println(properties);
}
}
yaml代码(写法一)
configuration:
properties:
string-array: [ Yi Dai,Guoxu Li ]
user-array: [ { id: 1001,username: Yi Dai,password: 123456a,gender: true },{ id: 1002,username: Guoxu Li,password: 123456b,gender: off } ]
yaml代码(写法二)
configuration:
properties:
string-array:
- Yi Dai
- Guoxu Li
user-array:
- id: 1001
username: Yi Dai
password: 123456a
gender: true
- id: 1002
username: Guoxu Li
password: 123456b
gender: off
输出结果
两种写法输出结果一致
Configuration.Properties(stringArray=[Yi Dai, Guoxu Li], userArray=[Configuration.User(id=1001, username=Yi Dai, gender=true), Configuration.User(id=1002, username=Guoxu Li, gender=false)])
特别注意:
- 在采用写法二绑定数组时,您应该注意每个元素都要换行,且
-
标识符后面应该有一个空格
集合类型
Java代码
package com.scfenzhi.config;
import lombok.Data;
import lombok.ToString;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;
import javax.annotation.PostConstruct;
import javax.annotation.Resource;
import java.util.List;
import java.util.Map;
import java.util.Set;
/**
* @Author: DaiYi
* @Email: 484201132@qq.com
* @CreateTime: 2022-01-15 15:51
* @Company: Sichuan Fenzhi International Trade Co., LTD
* @Description:
*/
@ToString
@Component
public class Configuration {
@Resource
private Properties properties;
@Data
@Component
@ConfigurationProperties(prefix = "configuration.properties")
private static class Properties {
private List<String> stringList;
private Set<Integer> integerSet;
private Map<String, Integer> stringIntegerMap;
}
@PostConstruct
public void print() {
System.out.println(properties);
}
}
yaml代码(写法一)
configuration:
properties:
string-list: [ YiDai,'Guoxu Li',"Yaxin Zhang" ]
integer-set: [ 1,3,5,7,9 ]
string-integer-map: { Dai: 18 , "Li": 23,'Zhang': 19 }
yaml代码(写法二)
configuration:
properties:
string-list:
- Yi Dai
- 'Guoxu Li'
- "Yaxin Zhang"
integer-set:
- 1
- 3
- 5
- 7
- 9
string-integer-map:
Dai: 18
"Li": 23
'Zhang': 19
输出结果
Configuration.Properties(stringList=[YiDai, Guoxu Li, Yaxin Zhang], integerSet=[1, 3, 5, 7, 9], stringIntegerMap={Dai=18, Li=23, Zhang=19})
特别注意:
- 在采用第二种写法绑定map时,您应该注意,此时不是数组了,不能在每一项前面加
-
标识符,如果您加了,这会导致结果的前面多了索引值和一个.
,如:0.Dai=18
。 - 绑定map时(无论何种写法),如果您的key是
String
类型的,那么存在一个问题,就是您多个字符之间的空格会被自动去除(加引号也不好使),但value不会。 -
List
集合默认创建java.util.ArrayList
-
Set
集合默认创建java.util.LinkedHashSet
-
Map
集合默认创建java.util.LinkedHashMap
复杂类型
Java代码
package com.scfenzhi.config;
import lombok.Data;
import lombok.ToString;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;
import javax.annotation.PostConstruct;
import javax.annotation.Resource;
import java.util.List;
import java.util.Map;
import java.util.Set;
/**
* @Author: DaiYi
* @Email: 484201132@qq.com
* @CreateTime: 2022-01-15 15:51
* @Company: Sichuan Fenzhi International Trade Co., LTD
* @Description:
*/
@ToString
@Component
public class Configuration {
@Resource
private Properties properties;
@Data
@Component
@ConfigurationProperties(prefix = "configuration.properties")
private static class Properties {
private User user;
private List<User> userList;
private Set<User> userSet;
private Map<Integer, User> userMap;
}
@Data
private static class User {
private Integer id;
private String username;
private Boolean gender;
private Car car;
}
@Data
private static class Car {
private Double price;
private String brand;
}
@PostConstruct
public void print() {
System.out.println(properties);
}
}
yaml代码(写法一)
configuration:
properties:
user: { id: 1001, username: Yi Dai,gender: true,car: { price: 1,brand: '宝驴' } }
user-list: [ { id: 1001, username: Yi Dai,gender: true,car: { price: 1,brand: '宝驴' } },{ id: 1002, username: Yaxin Zhang,gender: false,car: { price: 2,brand: '玛莎拉驴' } } ]
user-set: [ { id: 1001, username: Yi Dai,gender: true,car: { price: 1,brand: '宝驴' } },{ id: 1002, username: Yaxin Zhang,gender: false,car: { price: 2,brand: '玛莎拉驴' } } ]
user-map: { 1001: { id: 1001, username: Yi Dai,gender: true,car: { price: 1,brand: '宝驴' } },1002: { id: 1002, username: Yaxin Zhang,gender: false,car: { price: 2,brand: '玛莎拉驴' } } }
yaml代码(写法二)
configuration:
properties:
user:
id: 1001
username: Yi Dai
gender: true
car:
price: 1
brand: 宝驴
user-list:
- id: 1001
username: Yi Dai
gender: true
car:
price: 1
brand: 宝驴
- id: 1002
username: Yaxin Zhang
gender: false
car:
price: 1
brand: 玛莎拉驴
user-set:
- id: 1001
username: Yi Dai
gender: true
car:
price: 1
brand: 宝驴
- id: 1002
username: Yaxin Zhang
gender: false
car:
price: 1
brand: 玛莎拉驴
user-map:
1001:
id: 1001
username: Yi Dai
gender: true
car:
price: 1
brand: 宝驴
1002:
id: 1002
username: Yaxin Zhang
gender: false
car:
price: 1
brand: 玛莎拉驴
输出结果
两种方式都能正常绑定
Configuration.Properties(user=Configuration.User(id=1001, username=Yi Dai, gender=true, car=Configuration.Car(price=1.0, brand=宝驴)), userList=[Configuration.User(id=1001, username=Yi Dai, gender=true, car=Configuration.Car(price=1.0, brand=宝驴)), Configuration.User(id=1002, username=Yaxin Zhang, gender=false, car=Configuration.Car(price=2.0, brand=玛莎拉驴))], userSet=[Configuration.User(id=1001, username=Yi Dai, gender=true, car=Configuration.Car(price=1.0, brand=宝驴)), Configuration.User(id=1002, username=Yaxin Zhang, gender=false, car=Configuration.Car(price=2.0, brand=玛莎拉驴))], userMap={1001=Configuration.User(id=1001, username=Yi Dai, gender=true, car=Configuration.Car(price=1.0, brand=宝驴)), 1002=Configuration.User(id=1002, username=Yaxin Zhang, gender=false, car=Configuration.Car(price=2.0, brand=玛莎拉驴))})
其他细节
- 由于是松散绑定,所以您可以选择将属性名之间的多个单词的分割符改为下划线(
_
)