当死亡笼罩在脑海,请用生的信念打败它

上一章简单介绍了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());

    }

SpringBoot SpEL表达式(五十二)_lua

二.三 数学表达式计算处理

/**
     表达式处理
     */
    @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);

SpringBoot SpEL表达式(五十二)_Jep_02

所以用户在使用之前,先将所有的变量前面都加上 # 然后再进行拼接处理。

二.四 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));

    }

SpringBoot SpEL表达式(五十二)_Jep_03

二.五 集合处理

/**
      集合信息相关的调用
     */
    @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));
    }

SpringBoot SpEL表达式(五十二)_lua_04

二.六 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



谢谢您的观看,如果喜欢,请关注我,再次感谢 !!!