彻底搞懂 Spring spel 表达式(下)

彻底搞懂 Spring spel 表达式(下)


Spel概述

Spring表达式语言全称为“Spring Expression Language”,缩写为“SpEL”,类似于Struts2x中使用的OGNL表达式语言,能在运行时构建复杂表达式、存取对象图属性、对象方法调用等等,并且能与Spring功能完美整合,如能用来配置Bean定义。

表达式语言给静态Java语言增加了动态功能,Spel是Spring本身产品设计的产物。

SpEL是单独模块,只依赖于core模块,不依赖于其他模块,可以单独使用。

Spel能干什么?

表达式语言一般是用最简单的形式完成最主要的工作,减少我们的工作量。

SpEL支持如下表达式:

一、基本表达式: 字面量表达式、关系,逻辑与算数运算表达式、字符串连接及截取表达式、三目运算及Elivis表达式、正则表达式、括号优先级表达式;

二、类相关表达式: 类类型表达式、类实例化、instanceof表达式、变量定义及引用、赋值表达式、自定义函数、对象属性存取及安全导航表达式、对象方法调用、Bean引用;

三、集合相关表达式: 内联List、内联数组、集合,字典访问、列表,字典,数组修改、集合投影、集合选择;不支持多维内联数组初始化;不支持内联字典定义;

四、其他表达式:模板表达式。

注:SpEL表达式中的关键字是不区分大小写的。

由于我们上一篇已经分析过Spel表达式原理,这里主要示例Spel怎么使用

1、HelloWorld

public void test1() {
        ExpressionParser parser = new SpelExpressionParser();
        Expression expression = parser.parseExpression("('Hello' + ' World').concat(#end)");
        EvaluationContext context = new StandardEvaluationContext();
        context.setVariable("end", "!");
        System.out.println(expression.getValue(context));
    }

输出:

Hello World!

 2、定义模板使用

public void testParserContext() {
    ExpressionParser parser = new SpelExpressionParser();
    ParserContext parserContext = new ParserContext() {
        @Override
        public boolean isTemplate() {
            return true;
        }

        @Override
        public String getExpressionPrefix() {
            return "#{";
        }

        @Override
        public String getExpressionSuffix() {
            return "}";
        }
    };
    String template = "#{'Hello '}#{'World!'}";
    Expression expression = parser.parseExpression(template, parserContext);
    System.out.println(expression.getValue());
}

输出

Hello World!

3.字面量表达式

SpEL支持的字面量包括:字符串、数字类型(int、long、float、double)、布尔类型、null类型。

public void test2() {
    ExpressionParser parser = new SpelExpressionParser();

    String str1 = parser.parseExpression("'Hello World!'").getValue(String.class);
    int int1 = parser.parseExpression("1").getValue(Integer.class);
    long long1 = parser.parseExpression("-1L").getValue(long.class);
    float float1 = parser.parseExpression("1.1").getValue(Float.class);
    double double1 = parser.parseExpression("1.1E+2").getValue(double.class);
    int hex1 = parser.parseExpression("0xa").getValue(Integer.class);
    long hex2 = parser.parseExpression("0xaL").getValue(long.class);
    boolean true1 = parser.parseExpression("true").getValue(boolean.class);
    boolean false1 = parser.parseExpression("false").getValue(boolean.class);
    Object null1 = parser.parseExpression("null").getValue(Object.class);

    System.out.println("str1=" + str1);
    System.out.println("int1=" + int1);
    System.out.println("long1=" + long1);
    System.out.println("float1=" + float1);
    System.out.println("double1=" + double1);
    System.out.println("hex1=" + hex1);
    System.out.println("hex2=" + hex2);
    System.out.println("true1=" + true1);
    System.out.println("false1=" + false1);
    System.out.println("null1=" + null1);
}

输出

str1=Hello World!
int1=1
long1=-1
float1=1.1
double1=110.0
hex1=10
hex2=10
true1=true
false1=false
null1=null

4.算数运算表达式

SpEL支持加(+)、减(-)、乘(*)、除(/)、求余(%)、幂(^)运算。

public void test103(){
        ExpressionParser parser = new SpelExpressionParser();
        int result1 = parser.parseExpression("1+2-3*4/2").getValue(Integer.class);
        Float result2 = parser.parseExpression("4-3.6").getValue(Float.class);
        int result3 = parser.parseExpression("2^3").getValue(Integer.class);
        System.out.println(result1);
        System.out.println(result2);
        System.out.println(result3);
    }

输出

-3
0.4
8

5.关系表达式

等于(==)、不等于(!=)、大于(>)、大于等于(>=)、小于(<)、小于等于(<=),区间(between)运算。

SpEL同样提供了等价的“EQ” 、“NE”、 “GT”、“GE”、 “LT” 、“LE”来表示等于、不等于、大于、大于等于、小于、小于等于,不区分大小写。

public void test104(){
        ExpressionParser parser = new SpelExpressionParser();
        boolean result1 = parser.parseExpression("1 > 2").getValue(boolean.class);
        boolean result2 = parser.parseExpression("5 != 5").getValue(boolean.class);
        boolean result3 = parser.parseExpression("1 between {1, 2}").getValue(boolean.class);
        System.out.println(result1);
        System.out.println(result2);
        System.out.println(result3);
    }

输出

false
false
true

6.逻辑表达式

且(and或者&&)、或(or或者||)、非(!或NOT)。

public void test105(){
        ExpressionParser parser = new SpelExpressionParser();
        boolean result1 = parser.parseExpression("1 < 2 and (1 between {1, 2})").getValue(boolean.class);
        boolean result2 = parser.parseExpression("2>1 && (NOT true || NOT false)").getValue(boolean.class);
        System.out.println(result1);
        System.out.println(result2);
    }

输出

true
true

7.字符串连接及截取表达式

使用“+”进行字符串连接,使用“'String'[0] [index]”来截取一个字符,目前只支持截取一个,如“'Hello ' + 'World!'”得到“Hello World!”;而“'Hello World!'[0]”将返回“H”

public void test106(){
        ExpressionParser parser = new SpelExpressionParser();
        Object value = parser.parseExpression("'Hello ' + 'World!'").getValue();
        Object value1 = parser.parseExpression("('Hello ' + 'World!')[0]").getValue();
        System.out.println(value);
        System.out.println(value1);
    }

输出

Hello World!
H

8.三目运算

三目运算符 **“表达式1?表达式2:表达式3”**用于构造三目运算表达式,如“2>1?true:false”将返回true;

9.Elivis运算符

Elivis运算符**“表达式1?:表达式2”**从Groovy语言引入用于简化三目运算符的,当表达式1为非null时则返回表达式1,当表达式1为null时则返回表达式2,简化了三目运算符方式“表达式1? 表达式1:表达式2”,如“null?:false”将返回false,而“true?:false”将返回true;

10.正则表达式

使用“str matches regex,如“'123' matches '\d{3}'”将返回true;

11.括号优先级表达式

使用“(表达式)”构造,括号里的具有高优先级

12.类类型表达式

使用“T(Type)”来表示java.lang.Class实例,“Type”必须是类全限定名,“java.lang”包除外,即该包下的类可以不指定包名;使用类类型表达式还可以进行访问类静态方法及类静态字段。

    public void test107(){
        ExpressionParser parser = new SpelExpressionParser();
        //java.lang包类访问
        Class<String> result1 = parser.parseExpression("T(String)").getValue(Class.class);
        System.out.println(result1);

        //其他包类访问
        String expression2 = "T(ltd.newbee.mall.test.spel.SpelTest)";
        Class<SpelTest> value = parser.parseExpression(expression2).getValue(Class.class);
        System.out.println(value == SpelTest.class);

        //类静态字段访问
        int result3 = parser.parseExpression("T(Integer).MAX_VALUE").getValue(int.class);
        System.out.println(result3 == Integer.MAX_VALUE);

        //类静态方法调用
        int result4 = parser.parseExpression("T(Integer).parseInt('1')").getValue(int.class);
        System.out.println(result4);
    }

输出

class java.lang.String
true
true
1

13.类实例化

类实例化同样使用java关键字“new”,类名必须是全限定名,但java.lang包内的类型除外,如String、Integer。

ExpressionParser parser = new SpelExpressionParser();
    String result1 = parser.parseExpression("new String('路人甲java')").getValue(String.class);
    System.out.println(result1);

    Date result2 = parser.parseExpression("new java.util.Date()").getValue(Date.class);
    System.out.println(result2);

输出

路人甲java
Mon Dec 20 21:02:45 CST 2021

 

posted on 2021-12-20 21:05  真情的风  阅读(1220)  评论(0)    收藏  举报