简介
说明
本文用示例介绍SpringBoot的@Value的用法。
等效的方法
也可以通过如下方法获得配置的值:
2. ApplicationContextHolder.getContext().getEnvironment().getRequiredProperty(key);
ApplicationContextHolder见:SpringBoot-静态获得Bean的工具类 – 自学精灵
分类
@Value属性注入功能根据注入的内容来源可分为两类:通过配置文件的属性注入和通过非配置文件的属性注入。
通过配置文件的注入根据配置文件的来源又可分为两类:
- 默认的Spring Boot会自动加载的配置文件application.properties中的属性;
- 自定义配置文件中的属性,需要先通过@PropertySource加载。
非配置文件注入的类型又分为:
- 注入普通字符串
- 注入操作系统属性
- 注入表达式结果
- 注入其他Bean属性
- 注入文件资源
- 注入URL资源
@ConfigurationProperties与@Value
| 项 | @ConfigurationProperties | @Value |
|---|---|---|
| 类型 | Map、内部类、对象等。 | 不支持内部类、对象。 |
| spEl表达式 | 不支持 | 支持 |
| JSR303数据校验 | 支持 | 不支持 |
| 功能 | 一个列属性批量注入 | 单属性注入 |
格式问题
特殊字符
key和value都不能包含的字符:_、-、~、!、@、#、$、*、+、:等
如果value里有这些字符,用双引号包裹起来即可。
宽松绑定
以下方式写法相当于同一种写法。比如:yml用helloname,代码可以用helloName获取其值。
所有位置都支持宽松绑定,包括prefix、value。
helloname
helloName
HELLONAME
hello-name
hello_name
HELLO-NAME
基于配置文件注入
常用操作
application.properties
user.name=admin
@Value在Bean中的使用(注解到字段上)
@RestController
public class ValueController {
@Value("${user.name}")
private String name;
@Value("${user.password}")
private String password;
}
@Value在Bean中的使用(注解到参数上)
@RestController
public class ValueController {
private String password;
public ValueController(@Value("${user.password}")private String password){
this.password = password
}
}
还可以注入数组和列表形式
application.properties
tools=car,train,airplane
// 注入数组(自动根据","分割)
@Value("${tools}")
private String[] toolArray;
// 注入列表形式(自动根据","分割)
@Value("${tools}")
private List<String> toolList;
可拼接字符串
application.yml
custom: name: hello
Controller
package com.knife.controller;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
public class HelloController {
@Value("my name is: " + "${custom.name}")
private String name;
@GetMapping("/test")
public String test() {
return name;
}
}
结果:

可拼接配置字符串
application.yml
app: prefix: Hello suffix: World
Controller
package com.knife.example.controller;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RestController;
@Slf4j
@Api(tags = "测试")
@RestController
public class HelloController {
@Value("${app.prefix} ${app.suffix}")
private String combinedValue;
@ApiOperation("测试1")
@GetMapping("test")
public String test1() {
return combinedValue;
}
}
测试
访问:http://localhost:8080/test
结果

可指定配置文件
my.properties
user.password=pwd123
@Value在Bean中的使用(注解到字段上)
@PropertySource("classpath:my.properties")
@RestController
public class ValueController {
@Value("${user.name}")
private String name;
@Value("${user.password}")
private String password;
}
@Value在Bean中的使用(注解到参数上)
@PropertySource("classpath:my.properties")
@RestController
public class ValueController {
private String password;
ValueController(@Value("${user.password}") String password){
this.password = password
}
}
默认值注入
概述
说明
使用${} 或 #{}进行属性注入时,当获取不到值时可以设置默认值。
示例
// 若未配置ip,则使用默认值(127.0.0.1)
@Value("${ip:127.0.0.1}")
private String ip;
// 若未配置custom.myProperty,则使用默认值(Hello)
@Value("${custom.myProperty:Hello}")
private String myProperty;
// 如果属性中未配置custom.myProperty,则使用默认值(空字符串)
@Value("${custom.myProperty:}")
private String myProperty;
// 若未配置custom.myProperty,则使用默认值(null)
@Value("${custom.myProperty::#{null}}")
private String myProperty;
// 如果属性中配置custom.myProperty为空,则使用默认值(Hello)
@Value("#{${custom.myProperty}?:'Hello'}")
private String myProperty;
// 如果系统属性中未获取到port的值,则使用默认值(8888)。
@Value("#{systemProperties['port']?:'8888'}")
private String port;
${} 和 #{}获取不到值的区别
对于“获取不到值”,${}和#{}不一样。
情景1:无key,无value(即:没有配置)
${}:不报错,程序中myProperty的值为“Hello”
@Value("${custom.myProperty:Hello}")
private String myProperty;
#{}:启动时报错。
@Value("#{${custom.myProperty}?:'Tony'}")
private String myProperty;
报错信息:Caused by: java.lang.IllegalArgumentException: Could not resolve placeholder ‘custom.myProperty’ in value “#{${custom.myProperty}?:’Tony’}”
情景2:有key,无value(即:配置为空值)
application.yml
custom: myProperty:
${}:不报错。程序中myProperty的值为“” (空字符串)
@Value("${custom.myProperty:Tony}")
private String myProperty;
#{}:不报错。程序中myProperty的值为“Tony”
@Value("#{${custom.myProperty}?:'Tony'}")
private String myProperty;
SpEL
说明
SpEL(Spring Expression Language)即Spring表达式语言,可以在运行时查询和操作数据。使用#{…}作为定界符, 所有在大括号中的字符都将被认为是 SpEL。
SpEL详见:Spring-SpEL的用法 – 自学精灵
示例
// 注入普通字符串,相当于直接给属性默认值
@Value("这是我的字符串")
private String wechatSubscription;
// 注入配置
@Value("#{config.tool}")
private String tool;
// 注入操作系统属性
@Value("#{systemProperties['os.name']}")
private String systemPropertiesName;
// 注入表达式结果
@Value("#{ T(java.lang.Math).random() * 100.0 }")
private double randomNumber;
// 注入列表形式(自动根据"|"分割)
@Value("#{'${words}'.split('\\|')}")
private List<String> numList;
// 注入文件资源
@Value("classpath:config.xml")
private Resource resourceFile;
// 注入URL资源
@Value("http://www.choupangxia.com")
private URL homePage;

请先 !