您的位置:首页 > 编程语言 > Java开发

Spring Boot 学习笔记 2 : Random

2018-01-16 11:13 387 查看

官方文档介绍

The RandomValuePropertySource is useful for injecting random values (e.g. into secrets or test cases). It can produce integers, longs, uuids or strings, e.g.

RandomValuePropertySource 类通常用来注入 int,long,uuid 和 string 类型的随机值。

The random.int* syntax is OPEN value (,max) CLOSE where the OPEN,CLOSE are any character and value,max are integers. If max is provided then value is the minimum value and max is the maximum (exclusive).

random.int* 的语法是 OPEN value (,max) CLOSE 。OPEN 和 CLOSE 可以是 任意字符,用来分隔方法参数。value, max 是 int 类型的整数。如果 max 参数存在,则 value 表示取值范围的最小值,max 表示最大值(不包含 max)。

编写配置文件

application.properties 文件配置:

my.value=${random.value}
my.int=${random.int}
my.long=${random.long}
my.uuid=${random.uuid}
my.int.less.than.ten=${random.int(10)}
my.int.in.range=${random.int[1024,65536]}


application.yml 文件配置:

my:
value: ${random.value}
int: ${random.int}
long: ${random.long}
uuid: ${random.uuid}
int.less.than.ten: ${random.int(10)}
# 100前面和1000后面可以是 -,(,[ 等任意字符
int.in.range: ${random.int-100,1000-}


编写 Controller 类

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
@RequestMapping("/random")
public class RandomController {
private static Logger log = LoggerFactory.getLogger(RandomController.class);

//如果没有编写配置文件,此处可以直接使用${random.value}
@Value("${my.value}")
private String randomValue;

//如果没有编写配置文件,此处可以直接使用${random.int}
//int 类型也可以换成 String 类型
@Value("${my.int}")
private int randomInt;

//如果没有编写配置文件,此处可以直接使用${random.int(10)}
//int 类型也可以换成 String 类型
@Value("${my.int.less.than.ten}")
private int randomIntLessThanTen;

//如果没有编写配置文件,此处可以直接使用${random.int[100,1000]}
//int 类型也可以换成 String 类型
@Value("${my.int.in.range}")
private int randomIntRange;

//如果没有编写配置文件,此处可以直接使用${random.long}
//long 类型也可以换成 String 类型
@Value("${my.long}")
private long randomLong;

//如果没有编写配置文件,此处可以直接使用${random.uuid}
@Value("${my.uuid}")
private String randomUUID;

@RequestMapping("/value")
public String getValue() {
log.info("收到请求,randomValue : " + randomValue);
return "randomValue : " + randomValue;
}

@RequestMapping("/int")
public String getRandomInt() {
log.info("收到请求,randomInt : " + randomInt);
return "randomInt : " + randomInt;
}

@RequestMapping("/int/ten")
public String getRandomIntLessThanTen() {
log.info("收到请求,randomIntLessThanTen : " + randomIntLessThanTen);
return "randomIntLessThanTen : " + randomIntLessThanTen;
}

@RequestMapping("/int/range")
public String getRandomIntRange() {
log.info("收到请求,randomIntRange : " + randomIntRange);
return "randomIntRange : " + randomIntRange;
}

@RequestMapping("/long")
public String getRandomLong() {
log.info("收到请求,randomLong : " + randomLong);
return "randomLong : " + randomLong;
}

@RequestMapping("/uuid")
public String getRandomUUID() {
log.info("收到请求,randomUUID : " + randomUUID);
return "randomUUID : " + randomUUID;
}
}


使用浏览器或 Postman 测试





注意事项及异常

使用 @Value 注解注入的变量不能使用 static 修饰符修饰,否则变量的值无法注入成功。



编写配置文件时,键名不能以 “random” 开头,否则会抛出NumberFormatException 。



random:
value: ${random.value}
int: ${random.int}
long: ${random.long}
uuid: ${random.uuid}
int.less.than.ten: ${random.int(10)}
int.in.range: ${random.int-100,1000-}




原因是 RandomValuePropertySource 在解析 ${random.int.less.than.ten} 和 ${random.int.in.range} 表达式时:

1.会先调用 getProperty(String name) 方法截取前缀”random.” 后面的字符串,得到”int.less.than.ten”和”int.in.range”

2.然后会调用 getRandomValue(String type) 方法对剩下的字符串进行匹配,发现是以 “int” 作为前缀后

3.会调用 getRange(String type, String prefix) 方法,截取前缀”int.”后面到 length - 1 位置的字符串,得到”less.than.te”和”in.rang”

4.最后会调用 getNextIntInRange(String range) 方法,将剩下的字符串使用逗号分隔符切割后将返回数组的首个对象转换成 int 类型的数值作为 Random.nextInt(int bound) 方法的参数。

RandomValuePropertySource 类源码:

public class RandomValuePropertySource extends PropertySource<Random> {

/**
* Name of the random {@link PropertySource}.
*/
public static final String RANDOM_PROPERTY_SOURCE_NAME = "random";

private static final String PREFIX = "random.";

private static final Log logger = LogFactory.getLog(RandomValuePropertySource.class);

public RandomValuePropertySource(String name) {
super(name, new Random());
}

public RandomValuePropertySource() {
this(RANDOM_PROPERTY_SOURCE_NAME);
}

@Override
public Object getProperty(String name) {
if (!name.startsWith(PREFIX)) {
return null;
}
if (logger.isTraceEnabled()) {
logger.trace("Generating random property for '" + name + "'");
}
return getRandomValue(name.substring(PREFIX.length()));
}

private Object getRandomValue(String type) {
if (type.equals("int")) {
return getSource().nextInt();
}
if (type.equals("long")) {
return getSource().nextLong();
}
String range = getRange(type, "int");
if (range != null) {
return getNextIntInRange(range);
}
range = getRange(type, "long");
if (range != null) {
return getNextLongInRange(range);
}
if (type.equals("uuid")) {
return UUID.randomUUID().toString();
}
return getRandomBytes();
}

private String getRange(String type, String prefix) {
if (type.startsWith(prefix)) {
int startIndex = prefix.length() + 1;
if (type.length() > startIndex) {
return type.substring(startIndex, type.length() - 1);
}
}
return null;
}

private int getNextIntInRange(String range) {
String[] tokens = StringUtils.commaDelimitedListToStringArray(range);
int start = Integer.parseInt(tokens[0]);
if (tokens.length == 1) {
return getSource().nextInt(start);
}
return start + getSource().nextInt(Integer.parseInt(tokens[1]) - start);
}

private long getNextLongInRange(String range) {
String[] tokens = StringUtils.commaDelimitedListToStringArray(range);
if (tokens.length == 1) {
return Math.abs(getSource().nextLong() % Long.parseLong(tokens[0]));
}
long lowerBound = Long.parseLong(tokens[0]);
long upperBound = Long.parseLong(tokens[1]) - lowerBound;
return lowerBound + Math.abs(getSource().nextLong() % upperBound);
}

private Object getRandomBytes() {
byte[] bytes = new byte[32];
getSource().nextBytes(bytes);
return DigestUtils.md5DigestAsHex(bytes);
}

public static void addToEnvironment(ConfigurableEnvironment environment) {
environment.getPropertySources().addAfter(
StandardEnvironment.SYSTEM_ENVIRONMENT_PROPERTY_SOURCE_NAME,
new RandomValuePropertySource(RANDOM_PROPERTY_SOURCE_NAME));
logger.trace("RandomValuePropertySource add to Environment");
}

}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: