SpEL - Spring Expression Language - 快速入门

x33g5p2x  于2022-05-06 转载在 Spring  
字(12.1k)|赞(0)|评价(0)|浏览(512)

1. SpEL

注意: 强烈建议过一遍文档(不懂英文,直接Edge翻译、谷歌翻译网页)哦,这部分的内容并不多,跟着Demo敲就完事了

官方文档: https://docs.spring.io/spring-framework/docs/current/reference/html/core.html#expressions

1.1 功能

注意: 测试Demo用到的第三方工具包是Hutool哦

1.1.1 .属性名、方法名(必须是public) - (支持嵌套即多点点)
1.1.1.1 无判空操作

注意: .属性名 == 如果对象没有此字段定义,则会调用get属性名() 方法进行获取值

package top.linruchang.myblog;

import cn.hutool.core.lang.Console;
import org.junit.jupiter.api.Test;
import org.springframework.expression.Expression;
import org.springframework.expression.ExpressionParser;
import org.springframework.expression.spel.standard.SpelExpressionParser;

import java.util.Arrays;

/**
 * 作用:
 *
 * @author LinRuChang
 * @version 1.0
 * @date 2022/05/06
 * @since 1.8
 **/
public class SpELTest {

    @Test
    public void test1() {
        ExpressionParser parser = new SpelExpressionParser();
        Expression exp = parser.parseExpression("'Hello World'.bytes");
        byte[] bytes = (byte[]) exp.getValue();
        Console.log(bytes);
        System.out.println(Arrays.toString(bytes));
    }

    @Test
    public void test2() {
        ExpressionParser parser = new SpelExpressionParser();
        Expression exp = parser.parseExpression("'Hello World'.hash");
        Integer hashNum = exp.getValue(Integer.class);
        Console.log(hashNum);
        System.out.println(hashNum);
    }

    @Test
    public void test3() {
        ExpressionParser parser = new SpelExpressionParser();
        Expression exp = parser.parseExpression("5.MIN_VALUE");
        Integer MIN_VALUE = exp.getValue(Integer.class);
        Console.log(MIN_VALUE);
        System.out.println(MIN_VALUE);
    }

    @Test
    public void test4() {
        ExpressionParser parser = new SpelExpressionParser();
        Expression exp = parser.parseExpression("5L.MIN_VALUE");
        Long MIN_VALUE = exp.getValue(Long.class);
        Console.log(MIN_VALUE);
        System.out.println(MIN_VALUE);
    }

    @Test
    public void test5() {
        ExpressionParser parser = new SpelExpressionParser();
        Expression exp = parser.parseExpression("'5L'.getBytes");
        byte[] bytes = exp.getValue(byte[].class);
        Console.log(bytes);
        System.out.println(bytes);
    }

    
    @Test
    public void test6() {
        ExpressionParser parser = new SpelExpressionParser();
        Expression exp = parser.parseExpression("'5L'.getBytes.length");
        Integer byteLength = exp.getValue(Integer.class);
        Console.log(byteLength);
        System.out.println(byteLength);
    }

}

1.1.1.2 有判空操作 = 格式=》属性名?
public class DBTest {

public class DBTest {

    @Test
    public void test16() {

        SysUser sysUser = new SysUser();
        sysUser.setEmail("邮箱地址");
        SpelExpressionParser spelExpressionParser = new SpelExpressionParser();
        
        Expression expression = spelExpressionParser.parseExpression("email?.length");
        Object value = expression.getValue(sysUser);
        Console.log(value);

        //问好等价于下面那句话
        expression = spelExpressionParser.parseExpression("nickName?.length");
        value = expression.getValue(sysUser);
        Console.log(value);

        expression = spelExpressionParser.parseExpression("loginName != null ? loginName.length : null");
        value = expression.getValue(sysUser);
        Console.log(value);

        expression = spelExpressionParser.parseExpression("loginName.length");
        value = expression.getValue(sysUser);
        Console.log(value);
        
    }
    
}

1.1.2 直接解析调用Java代码 - 【不能直接正常调用静态方法,需要用实例对象.静态方法这样才能调成功】
/**
 * 作用:
 *
 * @author LinRuChang
 * @version 1.0
 * @date 2022/05/06
 * @since 1.8
 **/
public class SpELTest {

    /**
     * 正常使用的静态方法调用不了
     */
    @Test
    public void test7() {
        SpelExpressionParser spelExpressionParser = new SpelExpressionParser();
        Expression expression = spelExpressionParser.parseExpression("String.valueOf(5)");
        String value = expression.getValue(String.class);
        Console.log(value);
    }

    /**
     * 间接的调用静态方法
     */
    @Test
    public void test9() {
        SpelExpressionParser spelExpressionParser = new SpelExpressionParser();
        //静态方法
        Expression expression = spelExpressionParser.parseExpression("new Long('5').hashCode(5l)");
        Integer value = expression.getValue(Integer.class);
        Console.log(value);

        //成员方法
        expression = spelExpressionParser.parseExpression("new Long('5').floatValue()");
        Float value2 = expression.getValue(Float.class);
        Console.log(value2);
        
    }

}

1.1.3 解析自定义对象的值
public class SpELTest {

    /**
     * 静态方法调用不了
     */
    @Test
    public void test10() {

        //SysUser sysUser = new SysUser();
        //sysUser.setEmail("邮箱地址");
        Map sysUser = new HashMap();
        sysUser.put("email", "邮箱地址");
        

        SpelExpressionParser spelExpressionParser = new SpelExpressionParser();
        //解析某对象的email属性 - Bean对象
        //Expression expression = spelExpressionParser.parseExpression("email != null ? email.length() : 0");
        
        //Map == 键值对
        //Expression expression = spelExpressionParser.parseExpression("get('email') != null ? get('email').length() : 0");
        Expression expression = spelExpressionParser.parseExpression("['email'] != null ? ['email'].length() : 0");

        Integer value = expression.getValue(sysUser, Integer.class);
        Console.log(value);
        
    }

}

1.1.4 设置对象的值
方式1 - 表达式为属性名
public class SpELTest {
    /**
     * 静态方法调用不了
     */
    @Test
    public void test11() {
        SysUser sysUser = new SysUser();
        sysUser.setEmail("邮箱地址");

        SpelExpressionParser spelExpressionParser = new SpelExpressionParser();
        Expression expression = spelExpressionParser.parseExpression("nickName");
        expression.setValue(sysUser,"大家好");
        Console.log(sysUser);

    }

    /**
     * 静态方法调用不了
     */
    @Test
    public void test12() {
        SysUser sysUser = new SysUser();
        sysUser.setEmail("邮箱地址");

        SpelExpressionParser spelExpressionParser = new SpelExpressionParser();
        
        //设置el表达式执行标准,【仅能读取属性不能修改属性】
        EvaluationContext evaluationContext = SimpleEvaluationContext.forReadOnlyDataBinding().build();
        Expression expression = spelExpressionParser.parseExpression("nickName");
        expression.setValue(evaluationContext,sysUser,"大家好");
        Console.log(sysUser);
        
    }
}

方式2 - 表达式为赋值操作 - 写死
public class DBTest {

    /**
     * 静态赋值
     */
    @Test
    public void test12_2() {
        SysUser sysUser = new SysUser();
        sysUser.setEmail("邮箱地址");

        SpelExpressionParser spelExpressionParser = new SpelExpressionParser();

        
        Expression expression = spelExpressionParser.parseExpression("nickName = '大家好'");
        expression.getValue(sysUser);
        
        Console.log(sysUser);

    }

}

方式3 - 表达式为赋值操作 - 动态
public class DBTest {

    /**
     * 动态赋值
     */
    @Test
    public void test12_3() {
        SysUser sysUser = new SysUser();
        sysUser.setEmail("邮箱地址");

        SpelExpressionParser spelExpressionParser = new SpelExpressionParser();

        StandardEvaluationContext standardEvaluationContext = new StandardEvaluationContext();
        standardEvaluationContext.setVariable("newNickname", "大家好");
        Expression expression = spelExpressionParser.parseExpression("nickName = #newNickname");

        expression.getValue(standardEvaluationContext,sysUser);
        Console.log(sysUser);

    }
    
}

1.1.5 调用某类的静态方法
方式1(不建议):1.1.2一样,用实例对象调静态方法
方式2(建议):格式=》T(类的全限定名).静态方法(实参)
public class SpELTest {

    @Test
    public void test13() {

        SpelExpressionParser spelExpressionParser = new SpelExpressionParser();

        Expression expression = spelExpressionParser.parseExpression("T(java.lang.String).valueOf(5)");
        String value = expression.getValue(String.class);
        Console.log(value);

        Expression expression1 = spelExpressionParser.parseExpression("T(java.util.Arrays).asList(1,2,3,4)");
        List value1 = expression1.getValue(List.class);
        Console.log(value1);

    }
    
}

方式3(建议):格式=》#context传入的方法Key(实参) - 方法2的简写 - 个人更建议(方法2)
public class DBTest {

    @Test
    public void test15() {
        

        StandardEvaluationContext standardEvaluationContext = new StandardEvaluationContext();
        standardEvaluationContext.setVariable("addSuffixIfNot", ReflectUtil.getMethodByName(StrUtil.class,"addSuffixIfNot"));

        SpelExpressionParser spelExpressionParser = new SpelExpressionParser();
        Expression expression = spelExpressionParser.parseExpression("#addSuffixIfNot('name', '后缀')");
        
        Object value = expression.getValue(standardEvaluationContext);
        Console.log(value);
        

    }
    
}

1.1.6 三元运算符
public class DBTest {

    @Test
    public void test14() {
        SpelExpressionParser spelExpressionParser = new SpelExpressionParser();
        
        //简写的三元运算符
        StandardEvaluationContext standardEvaluationContext = new StandardEvaluationContext();
        standardEvaluationContext.setVariable("content", "发的范德萨发");
        standardEvaluationContext.setVariable("content2", null);

        Expression expression = spelExpressionParser.parseExpression("#content?:'无内容'");
        //Expression expression = spelExpressionParser.parseExpression("#content? #content:'无内容'"); //不可写成这样会报错,前面必须是java的布尔值类型
        Object value = expression.getValue(standardEvaluationContext);
        Console.log(value);

        
        
        expression = spelExpressionParser.parseExpression("#content2?:'无内容'");
        value = expression.getValue(standardEvaluationContext);
        Console.log(value);

        //标准的三元运算符
        expression = spelExpressionParser.parseExpression("T(cn.hutool.core.util.StrUtil).isNotBlank(#content2) ? #content2 : '无内容'");
        value = expression.getValue(standardEvaluationContext);
        Console.log(value);

    }
    
}

1.1.7 容器(Iterable)- 选择符合条件的元素 - 格式=》容器.?[符合元素的条件]

介绍:类似Stream.filter作用

public class DBTest {

    @Test
    public void test18() {
        List<SysUser> sysUsers = new ArrayList<>();
        sysUsers.add(new SysUser());
        IntStream.range(1,5).forEachOrdered(num -> {
            SysUser sysUser = new SysUser();
            sysUser.setEmail("邮箱" + num);
            sysUser.setId(String.valueOf(num));
            sysUsers.add(sysUser);
        });


        StandardEvaluationContext standardEvaluationContext = new StandardEvaluationContext();
        standardEvaluationContext.setVariable("sysUsers2", sysUsers);
        standardEvaluationContext.setVariable("sysUsers3", Collections.emptyList());
        standardEvaluationContext.setVariable("sysUsers4", null);

        SpelExpressionParser spelExpressionParser = new SpelExpressionParser();
        //下面四者等价,第三个可能会出现空指针问题
        Expression expression = spelExpressionParser.parseExpression("#root?.?[id > '3']");
        //Expression expression = spelExpressionParser.parseExpression("#root?.?[id > '3']");
        //Expression expression = spelExpressionParser.parseExpression("#root.?[id > '3']");
        //Expression expression = spelExpressionParser.parseExpression("?[id > '3']");

        List value = expression.getValue(sysUsers, List.class);
        Console.log(value);

        expression = spelExpressionParser.parseExpression("#sysUsers2?.?[email == '邮箱3']");
        value = expression.getValue(standardEvaluationContext, List.class);
        Console.log(value);

        expression = spelExpressionParser.parseExpression("#sysUsers3?.?[email == '邮箱3']");
        value = expression.getValue(standardEvaluationContext, List.class);
        Console.log(value);

        expression = spelExpressionParser.parseExpression("#sysUsers4?.?[email == '邮箱3']");
        value = expression.getValue(standardEvaluationContext, List.class);
        Console.log(value);

    }
}

1.1.8 容器(Iterable)-字段投影 - 格式=》容器.![字段名]

介绍:类似Stream.map作用

public class DBTest {

    @Test
    public void test17() {
        List<SysUser> sysUsers = new ArrayList<>();
        sysUsers.add(new SysUser());
        IntStream.range(1,5).forEachOrdered(num -> {
            SysUser sysUser = new SysUser();
            sysUser.setEmail("邮箱" + num);
            sysUsers.add(sysUser);
        });


        StandardEvaluationContext standardEvaluationContext = new StandardEvaluationContext();
        standardEvaluationContext.setVariable("sysUsers2", sysUsers);
        standardEvaluationContext.setVariable("sysUsers3", Collections.emptyList());
        standardEvaluationContext.setVariable("sysUsers4", null);

        SpelExpressionParser spelExpressionParser = new SpelExpressionParser();
        //下面四者等价,第三个可能会出现空指针异常问题
        Expression expression = spelExpressionParser.parseExpression("#this?.![email]");
        //Expression expression = spelExpressionParser.parseExpression("#root?.![email]");
        //Expression expression = spelExpressionParser.parseExpression("#root.![email]");
        //Expression expression = spelExpressionParser.parseExpression("![email]");

        List value = expression.getValue(sysUsers, List.class);
        Console.log(value);

        expression = spelExpressionParser.parseExpression("#sysUsers2?.![email]");
        value = expression.getValue(standardEvaluationContext, List.class);
        Console.log(value);

        expression = spelExpressionParser.parseExpression("#sysUsers3?.![email]");
        value = expression.getValue(standardEvaluationContext, List.class);
        Console.log(value);

        expression = spelExpressionParser.parseExpression("#sysUsers4?.![email]");
        value = expression.getValue(standardEvaluationContext, List.class);
        Console.log(value);

    }
}

1.1.9 模板内容解析 - 仅解析 == #{}中括号里面的内容
public class DBTest {
    @Test
    public void test19() {

        SpelExpressionParser spelExpressionParser = new SpelExpressionParser();
        
        //模板变量解析开始${   待解析的内容  解析结束}
        TemplateParserContext templateParserContext = new TemplateParserContext();
        Expression expression = spelExpressionParser.parseExpression("你好我是你爸爸:#{#fatherName}",templateParserContext);

        StandardEvaluationContext standardEvaluationContext = new StandardEvaluationContext();
        standardEvaluationContext.setVariable("fatherName","Tom");

        Object value = expression.getValue(standardEvaluationContext);
        Console.log(value);
        

    }
}

相关文章