当死亡笼罩在脑海,请用生的信念打败它
上一章简单介绍了SpringBoot 事件监听处理(五十一), 如果没有看过,请观看上一章
一. 解析器
我们在生活中,常常会用到表达式计算, 如 传入一个字符串 a+b+c+d, 然后指定 a,b,c,d 的值。
让其计算出最后的结果。
可以用 jep 进行处理
jep 的使用
一.一 pom.xml 添加依赖
<dependency>
<groupId>jep</groupId>
<artifactId>jep</artifactId>
<version>2.24</version>
</dependency>
一.二 测试验证
注意,要将添加 变量 写在 表达式的前面。
即 先调用 addVariable() 方法设置变量,在 parseExpression() 处理表达式.
/**
* 主要是数学公式
*
* @author yuejianli
* @date 2023-05-31
*/
@Slf4j
public class JepTest {
@Test
public void oneTest() {
// 1. 构建类
JEP jep = new JEP();
//2. 添加变量
jep.addVariable("a",1);
jep.addVariable("b",2);
jep.addVariable("c",3);
jep.addVariable("d",4);
jep.addVariable("e",5);
//3. 处理表达式
jep.parseExpression("a+b-c+d-e");
//4. 获取结果
log.info(">>> 获取结果: {}", jep.getValue());
}
}
10:57:01.655 [main] INFO top.yueshushu.jep.test.JepTest - >>> 获取结果: -1.0
也可以用中文来表示变量信息:
@Test
public void twoTest() {
// 1. 构建类
JEP jep = new JEP();
//2. 添加变量
jep.addVariable("单价",1);
jep.addVariable("数量",2);
//3. 处理表达式
jep.parseExpression("单价*数量");
//4. 获取结果
log.info(">>> 获取结果: {}", jep.getValue());
}
10:58:50.620 [main] INFO top.yueshushu.jep.test.JepTest - >>> 获取结果: 2.0
JEP 一般只计算数学表达式, Spring 提供的 SpEL 有更强大的功能.
二. SpEL 的使用
不需要添加额外的依赖, spring boot 中已经包含了。
二.一 普通的数字计算公式
@SpringBootTest
@RunWith(SpringRunner.class)
@Slf4j
public class ELTest {
/**
简单的处理
*/
@Test
public void oneTest() {
//1. 构建对象
ExpressionParser expressionParser = new SpelExpressionParser();
//2. 解析表达式
Expression expression = expressionParser.parseExpression("1+2+3");
//3. 获取结果
log.info("获取结果: {}", expression.getValue());
}
}
2023-06-09 11:01:32.383 INFO 13260 --- [ main] top.yueshushu.jep.test.ELTest : 获取结果: 6
二.二 boolean 相应的表达式
/**
获取 boolean 等相应的信息
*/
@Test
public void twoTest() {
ExpressionParser expressionParser = new SpelExpressionParser();
log.info("3>2 为: {}", expressionParser.parseExpression("3>2").getValue());
log.info("1!=1 为: {}", expressionParser.parseExpression("1!=1").getValue());
log.info("3>2 && 2>3 为: {}", expressionParser.parseExpression("3>2 && 2>3").getValue());
log.info("3>2 || 2>3 为: {}", expressionParser.parseExpression("3>2 || 2>3").getValue());
// 普通字符串方法调用
log.info("hello.substring(3): {}", expressionParser.parseExpression("'hello'.substring(3)").getValue());
}
二.三 数学表达式计算处理
/**
表达式处理
*/
@Test
public void threeTestTrue() {
ExpressionParser expressionParser = new SpelExpressionParser();
// 创建数据上下文
StandardEvaluationContext standardEvaluationContext = new StandardEvaluationContext();
// 数据上下文设置变量
Map<String,Object> paramMap = new HashMap<>();
paramMap.put("a",1);
paramMap.put("b",2);
paramMap.put("c",3);
paramMap.put("d",4);
paramMap.put("e",5);
standardEvaluationContext.setVariables(paramMap);
// 解析表达式,获取数据, 注意,传入的变量前面需要加入 # 号, 指定这是一个变量
Object value = expressionParser.parseExpression("#a+#b-#c+#d-#e").getValue(standardEvaluationContext);
log.info(">>> 获取结果: {}", value);
}
注意看, 表达式 前面都加上 # 号才可以
2023-06-09 11:04:10.793 INFO 14988 --- [ main] top.yueshushu.jep.test.ELTest : >>> 获取结果: -1
如果变量前不加 # 号的话, 即:
Object value = expressionParser.parseExpression("a+b-c+d-e").getValue(standardEvaluationContext);
所以用户在使用之前,先将所有的变量前面都加上 # 然后再进行拼接处理。
二.四 Bean 对象处理
User.java 实体
@Data
@AllArgsConstructor
@NoArgsConstructor
public class User {
private String name;
}
/**
处理对象, 获取对象里面的属性和方法
*/
@Test
public void beanTest() {
ExpressionParser expressionParser = new SpelExpressionParser();
// 需要创建上下文
StandardEvaluationContext standardEvaluationContext = new StandardEvaluationContext();
standardEvaluationContext.setVariable("user",new User("岳泽霖"));
// 执行信息
log.info("获取name的值: {}", expressionParser.parseExpression("#user.name").getValue(standardEvaluationContext));
log.info("获取name的值,方法: {}", expressionParser.parseExpression("#user.getName()").getValue(standardEvaluationContext));
}
二.五 集合处理
/**
集合信息相关的调用
*/
@Test
public void collectionTest() {
//创建表达式解析器
ExpressionParser expressionParser = new SpelExpressionParser();
//创建数据上下文
StandardEvaluationContext evaluationContext = new StandardEvaluationContext();
//设置数组变量
evaluationContext.setVariable("users", new User[]{new User("岳泽霖")});
//设置集合变量
evaluationContext.setVariable("userList", Collections.singletonList(new User("岳泽霖")));
//设置map变量
evaluationContext.setVariable("userMap", Collections.singletonMap("name", new User("岳泽霖")));
log.info("数组 {}",expressionParser.parseExpression("#users[0].name").getValue(evaluationContext));
log.info("集合 {}",expressionParser.parseExpression("#userList[0].name").getValue(evaluationContext));
log.info("map {}",expressionParser.parseExpression("#userMap['name'].name").getValue(evaluationContext));
}
二.六 ioc 配置类
二.六.一 配置一个Bean
@Configuration
public class BeanConfig {
@Bean("iocUser")
public User iocUser(){
return new User("IOC用户");
}
}
二.六.二 ioc 使用
@Test
public void iocTest() {
//创建表达式解析器
ExpressionParser expressionParser = new SpelExpressionParser();
//创建数据上下文
StandardEvaluationContext evaluationContext = new StandardEvaluationContext();
//创建IOC容器上下文
ApplicationContext context = new AnnotationConfigApplicationContext(BeanConfig.class);
//创建bean表达式上下文
BeanExpressionContext beanExpressionContext = new BeanExpressionContext((ConfigurableBeanFactory) context.getAutowireCapableBeanFactory(), null);
evaluationContext.setRootObject(beanExpressionContext);
//添加属性访问器 从IOC容器中获取bean
evaluationContext.addPropertyAccessor(new BeanExpressionContextAccessor());
log.info("{}",expressionParser.parseExpression("#{iocUser.name}", new TemplateParserContext()).getValue(evaluationContext));
}
2023-06-09 11:10:07.559 INFO 16104 --- [ main] top.yueshushu.jep.test.ELTest : IOC用户
本章节的代码放置在 github 上:
https://github.com/yuejianli/Function/tree/develop/SpringBoot_Expression
谢谢您的观看,如果喜欢,请关注我,再次感谢 !!!