spring @Value注入map、List、Bean、static变量方式及详细使用
使用@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数据校验 | 支持 | 不支持 |
复杂类型封装 | 支持 | 不支持 |