使用@Value注入map、List
實體類
List:
@Value("${test.list.ids:1,2,3}")
private List<String> testList;
或者
@Value("${test.list.ids:1,2,3}")
private String[] testList;
List 指定分隔符
@Value("#{'${test.list}'.split(',')}")
private List<String> list;
配置文件
test.list: topic1,topic2,topic3
split(‘,’)只以’,’為分隔符,也可以換成別的
當配置文件中沒有key時,也可以使用key:default_value
的方法設置默認值
map:
@Value("#{${test.maps}}")
private Map<String,String> maps;
配置文件
test.maps: "{key1: 'value1', key2: 'value2'}"
ps: 注意上面的map解析中,一定要用""把map所對應的value包起來,要不然解析會失敗,導致不能轉成 Map<String,String>。
通過@Value( ) 給靜態變量注入值
spring 不允許/不支持把值注入到靜態變量中,如:
@Value("${ES.CLUSTER_NAME}")
private static String CLUSTER_NAME;
在方法中獲得的CLUSTER_NAME,會得到null
解決
好在spring支持set方法注入,我們可以利用非靜態setter 方法注入靜態變量。如:
private static String CLUSTER_NAME;
@Value("${ES.CLUSTER_NAME}")
public void setClusterName(String clusterName) {
CLUSTER_NAME = clusterName;
}
@Value必須修飾在方法上,且set方法不能有static 這樣就能獲得值了
Spring中使用@Value如何按類型注入值
示例:
容器中,有一個Runnable的bean
@Configuration
public class Config {
@Bean("myrun")
public Runnable run() {
return () -> System.out.println("this is spring run");
}
}
想使用@Value的方式,把這個bean注入進來,這種是按bean的名字注入。
@Service
public class Runner {
@Value("#{myrun}")
private Runnable run;
public void run() {
run.run();
}
}
#{…}和${…}
${…}用法
通過@Value(“${spelDefault.value}”)可以獲取屬性文件中對應的值,但是如果屬性文件中沒有這個屬性,則會報錯。可以通過賦予默認值解決這個問題,如
@Value("${test.value:127.0.0.1}")
#{…}用法
#{…}的{}里面的內容必須符合SpEL表達式,詳細的語法,以后可以專門開新的文章介紹,這里只演示簡單用法:
${…}和#{…}混合使用
${...}和#{...}可以混合使用,如下文代碼執行順序:通過
${server.name}
從屬性文件中獲取值並進行替換,然后就變成了 執行SpEL表達式
#{'server1,server2,server3'.split(',')}
// SpEL: 傳入一個字符串,根據","切分后插入列表中, #{}和${}配置使用(注意單引號,注意不能反過來${}在外面,#{}在里面)
@Value("#{'${server.name}'.split(',')}") private List<String> servers;
在上文中在#{}外面,${}在里面可以執行成功,那么反過來是否可以呢${}在外面,#{}在里面,是不能。
因為spring執行${}是時機要早於#{}。${}在外面,#{}在里面是非法操作。
小結
#{…} 主要用於加載外部屬性文件中的值
${…} 用於執行SpEl表達式,並將內容賦值給屬性
#{…} 和${…} 可以混合使用,但是必須#{}外面,${}在里面
ConfigurationProperties注入
@Data
@ConfigurationProperties(prefix = "jdbc")
public class SpringBootProperty {
private String url;
private String driverClassName;
private String username;
private String password;
}
注解解析:
@ConfigurationProperties注解聲明當前類為屬性讀取類
prefix:讀取數據文件中,前綴為jdbc的值
在類上定義各個屬性,名稱必須與屬性文件中jdbc.后面部分一致
屬性文件是定義在application.yml文件中的
spring:
application:
name: property
server:
port: 8083
jdbc:
driverClassName: com.mysql.jdbc.Driver
url: jdbc:mysql://127.0.0.1:3306/test
username: root
password: 123
二者區別 | @ConfigurationProperties | @Value |
---|---|---|
功能 | 批量注入配置文件中的屬性 | 一個個指定 |
松散綁定(松散語法) | 支持 | 不支持 |
SpEL | 不支持 | 支持 |
JSR303數據校驗 | 支持 | 不支持 |
復雜類型封裝 | 支持 | 不支持 |