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"); } }
相关文章推荐
- Spring Boot 学习笔记(二)
- Spring boot学习笔记 003——Spring boot持久层
- 学习笔记_JavaSE_14_正则表达式、Math、Random、System、BigInteger、BigDecimal、Date与DateFormat、Calendar
- spring boot 学习笔记(5) 解决HttpServletRequest inputStream只能读取一次的问题
- JAVA学习笔记(三十五)- 随机读写文件 RandomAccessFile
- Python学习笔记17:标准库之数学相关(math包,random包)
- Java学习笔记(八)--基本数据类型包装类 Math类 Random类 Date类
- 【学习笔记】使用Math.floor与Math.random取随机整数的方法详解
- 黑马程序员_学习笔记:14) Properties、PrintStream、SequenceInputStream:序列流、RandomAccessFile、管
- Spring Boot 学习笔记1---初体验之3分钟启动你的Web应用
- Spring Boot学习笔记-入门篇
- Spring Boot学习笔记----Schedule
- java.util.Random学习笔记
- Spring Boot学习笔记-错误处理及自定义
- Python模块学习笔记— —random
- java 学习笔记 随机数产生的两种办法Math.random()和Random类
- Java基础学习笔记 -- 6(Scanner、Random)
- Spring Boot学习笔记(一)
- Random 学习笔记
- 【JavaSE学习笔记】常用类介绍04_System,Date,Math,Random,Pattern