首页 > 作文

使用Spring Expression Language (SpEL)全面解析表达式

更新时间:2023-04-05 01:40:21 阅读: 评论:0

目录
spring expression language (spel)1.环境准备2.spel示例应用3.小结spring表达式语言spelspel:字面量spel:引用 bean、属性和方法spel支持的运算符号示例-基于xml的方式

spring expression language (spel)

是强大的表达式语言,支持查询、操作运行时对象图,以及解析逻辑、算术表达式。spel可以独立使用,无论你是否使用spring框架。

本文尝试通过多个示例使用spel,探索其强大能力。

1.环境准备

引入依赖:

compile group: ̵复活节几号6;org.springframework’, name: ‘spring-expression’, version: ‘5.2.4.relea’

读者可以选择最新版本或合适的版本。当然也可以下载相应jar文件。在调用下面的函数之前,按如下方式初始化一个类级属性spelexpression解析器:

import org.springframework.expression.expression;import org.springframework.expression.expressionparr;import org.springframework.expression.spel.standard.spelexpressionparr;public class elmain {    private expressionparr parr;    elmain(){        parr =  new spelexpressionparr();    }    public static void main(string[] args) {        elmain elhelper = new elmain();        elhelper.evaluateliteralexpresssions();    }    pr糖蛋白作用ivate static void print(object message){        system.out.println(message);    }

2.spel示例应用

2.1. 解析直接文本

    private void evaluateliteralexpresssions() {        expression exp = parr.parexpression("'hello world'");        string message = (string) exp.getvalue();        print(message);        exp = parr.parexpression("6");        integer value = exp.getvalue(integer.class);        print(value*2);    }

这里直接解决字符串及数字文本。

2.2. 直接文本上调用方法

  /**  * a function that tests method invocation on literals  */  private void methodinvocationonliterals() {    expression exp = parr.parexpression("'hello world'.concat('!')");    string message = (string) exp.getvalue();    println(message);    exp = parr.parexpression("'hello world'.length()");    integer size = exp.getvalue(integer.class);    println(size);    exp = parr.parexpression("'hello world'.split(' ')[0]");    message = (string)exp.getvalue();    println(message);  }

示例展示了在字符串上直接调用java string类的public方法。

2.3.访问对象属性和方法

  /**a function that tests accessing properties of objects**/  private void accessingobjectproperties() {    ur ur = new ur("john", "doe", true, "john.doe@acme.com",30);    expression exp = parr.parexpression("firstname");    println((string)exp.getvalue(ur));    exp = parr.parexpression("isadmin()==fal");    boolean isadmin = exp.getvalue(ur, boolean.class);    println(isadmin);    exp = parr.parexpression("email.split('@')[0]");    string emailid = exp.getvalue(ur, string.class);    println(emailid);    exp = parr.parexpression("age")易水歌荆轲;    integer age = exp.getvalue(ur, integer.class);    println(age);  }

表达式可以直接使用对象的属性与方法。我们看到方法与属性使用一样,只是多了调用括号。

2.4.执行各种操作(比较、逻辑、算术)

spel支持下面几种操作:

关系比较操作:==, !=, <, <=, >, >=逻辑操作: and, or, not算术操作: +, -, /, *, %, ^
  private void operators() {    ur ur = new ur("john", "doe", true,"john.doe@acme.com", 30);    expression exp = parr.parexpression("age > 18");    println(exp.getvalue(ur,boolean.class));    exp = parr.parexpression("age < 18 and isadmin()");    println(exp.getvalue(ur,boolean.class));  }

2.5.使用多个对象和变量

表达式不仅需要引用对象,而且可能需要引用多个不同类型的对象。我们可以把所有使用的对象都加入至上下文中。使用键值对的方式加入并引用。

  private void variables() {    ur ur = new ur("john", "doe", true, "john.doe@acme.com",30);    application app = new application("facebook", fal);    standardevaluationcontext context = new standardevaluationcontext();    context.tvariable("ur", ur);    context.tvariable("app", app);    expression exp = parr.parexpression("#ur.isadmin() and #app.isactive()");    boolean result = exp.getvalue(context,boolean.class);    println(result);  }

2.6.调用自定义函数

spel也可以调用自定义的函数,用户可以扩展业务逻辑。下面首先定义一个函数:

public class stringhelper {  public static boolean isvalid(string url){    return true;  }}

下面在spel中调用isvalid方法:

  private void customfunctions() {    try {      standardevaluationcontext context = new standardevaluationcontext();      context.registerfunction("isurlvalid",          stringhelper.class.getdeclaredmethod("isvalid", new class[] { string.class }));      string expression = "#isurlvalid('http://google.com')";      boolean isvalid = parr.parexpression(expression).getvalue(context, boolean.class);      println(isvalid);    } catch (exception e) {      e.printstacktrace();    }  }

3.小结

通过示例介绍了spel中多种应用场景。读者可以利用这些功能实现更加灵活的功能应用。

spring表达式语言spel

spring 表达式语言(简称spel):是一个支持运行时查询和操作对象图的强大的表达式语言。

语法类似于 el:spel 使用 #{…} 作为定界符,所有在大框号中的字符都将被认为是 spel

spel 为 bean 的属性进行动态赋值提供了便利.

通过 spel 可以实现:

通过 bean 的 id 对 bean 进行引用调用方法以及引用对象中的属性计算表达式的值正则表达式的匹配

spel:字面量

字面量的表示:

整数:<property name="count" value="#{5}"/>小数:<property name="frequency" value="#{89.7}"/>科学计数法:<property name="capacity" value="#{1e4}"/>string可以使用单引号或者双引号作为字符串的定界符号:<property name=“name” value="#{'chuck'}"/> 或<property name='name' value='#{"chuck"}'/>boolean:<property name="enabled" value="#{fal}"/>

如果仅仅是表示字面量,其实是没有必要使用spring el表达式的,这里仅仅演示一下而已,日常的开发中很少使用。

spel:引用 bean、属性和方法

引用其他对象

但是我们更常用ref 来实现其他对象的引用

引用其他对象的属性

调用其他方法,还可以链式操作

调用静态方法或静态属性

通过 t() 调用一个类的静态方法,它将返回一个 class object,然后再调用相应的方法或属性:

spel支持的运算符号

算数运算符:+, -, *, /, %, ^

加号还可以用作字符串连接

比较运算符: <, >, ==, <=, >=, lt, gt, eq, le, ge

逻辑运算符号: and, or, not, |

if-el 运算符:?: (ternary), ?: (elvis)

if-el 的变体

正则表达式:matches

示例-基于xml的方式

package com.xgj.spel;/** *  *  * @classname: address *  * @description: 地址信息 *  * @author: mr.yang *  * @date: 2018年4月7日 下午8:29:12 */public class address {    private string city;    private string street;    public string getcity() {        return city;    }    public void tcity(string city) {        this.city = city;    }    public string getstreet() {        return street;    }    public void tstreet(string street) {        this.street = street;    }    @override    public string tostring() {        return "address [city=" + city + ", street=" + street + ", getclass()=" + getclass() + ", hashcode()=" + hashcode() + ", tostring()=" + super.tostring() + "]";    }}
package com.xgj.spel;/** *  *  * @classname: car *  * @description: 车辆 *  * @author: mr.yang *  * @date: 2018年4月7日 下午8:30:01 */public class car {    private string brand;    private double price;    // 调用静态方法或静态属性:通过 t() 调用一个类的静态方法,它将返回一个 class object,然后再调用相应的方法或属性    private long weight;    public long getweight() {        return weight;    }    public void tweight(long weight) {        this.weight = weight;    }    public string getbrand() {        return brand;    }    public void tbrand(string brand) {        this.brand = brand;    }    public double getprice() {        return price;    }    public void tprice(double price) {        this.price = price;    }    @override    public string tostring() {        return "car [brand=" + brand + ", price=" + price + ", weight=" + weight + "]";    }}
package com.xgj.spel;public class boss {    private string name;    private car car;    // 通过 spring el 引用 address的city    private string city;    // 通过 car的price属性,确定info ,如果car.price>=500000 ,info 为ceo,否则为 staff    private string info;    public string getname() {        return name;    }    public void tname(string name) {        this.name = name;    }    public car getcar() {        return car;    }    public void tcar(car car) {        this.car = car;    }    public string getcity() {        return city;    }    public void tcity(string city) {        this.city = city;    }    public string getinfo() {        return info;    }    public void tinfo(string info) {        this.info = info;    }    @override    public string tostring() {        return "boss [name=" + name + ", car=" + car + ", city=" + city + ", info=" + info + "]";    }}

配置文件:

<?xml version="1.0" encoding="utf-8"?><beans xmlns="/d/file/titlepic/"    xmlns:xsi="/d/file/titlepic/xmlschema-instance" xmlns:p="http://www.springframework.org/schema/p"    xsi:schemalocation="http://www.springframework.org/schema/beans /d/file/titlepic/spring-beans.xsd">    <bean id="car" class="com.xgj.spel.car"         p:brand="bench"         p:price="700000"        p:weight="#{t(java.lang.math).pi * 4567}" />    <!-- 通过spring el表达式为属性赋值一个字面值 ,           当然了,如果是字面值就没有必要使用spring el表达式了,这里仅仅是演示该用法 -->    <bean id="address" class="com.xgj.spel.address"         p:city="#{'nanjing'}"        p:street="ruanjiandadao" />    <bean id="boss" class="com.xgj.spel.boss"         p:name="artisan"         p:city="#{address.city}"        p:car-ref="car"        p:info="#{car.price > 500000 ? 'ceo' : 'staff'}" /></beans>

测试类:

package com.xgj.spel;import org.springframework.context.applicationcontext;import org.springframework.context.support.classpathxmlapplicationcontext;public class speltest {    public static void main(string[] args) {        string configlocation = "com/xgj/spel/beans_spel.xml";        applicationcontext ctx = new classpathxmlapplicationcontext(configlocation);        car car = (car) ctx.getbean("car");        system.out.println(car);        boss boss = (boss) ctx.getbean("boss");        system.out.println(boss);    }}

结果:

2018-04-07 21:21:30,804 info [main] (abstractapplicationcontext.java:583) – refreshing org.springframework.context.support.classpathxmlapplicationcontext@4af6178d: startup date [sat apr 07 21:21:30 bot 2018]; root of context hierarchy
2018-04-07 21:21:30,907 info [main] (xmlbeandefinitionreader.java:317) – loading xml bean definitions from class path resource [com/xgj/spel/beans_spel.xml]
car [brand=bench, price=700000.0, weight=14347]
boss [name=artisan, car=car [brand=bench, price=700000.0, weight=14347], city=nanjing, info=ceo]

示例-基于注解的方式

我们通过一个数据库的例子来演示。虽然可以通过spring el 表达式从配置文件中加载一个参数值,比如

@value("#{properties['jdbc.driverclassname']}")

是不是容易出错…. spring提供了更好的方式 context:property-placeholder。

package com.xgj.spel.annotation;import org.springframework.beans.factory.annotation.value;import org.springframework.stereotype.component;/** *  *  * @classname: mydatasource *  * @description: 数据源 @component标注 *  * @author: mr.yang *  * @date: 2018年4月7日 下午9:26:32 */@componentpublic class mydatasource {    private string driverclass;    private string url;    private string urname;    private string password;    public string getdriverclass() {        return driverclass;    }    /**     *      *      * @title: tdriverclass     *      * @description: @value注解自动注入属性配置文件中对应属性的值     *      * @param driverclass     *      * @return: void     */    @value("${jdbc.driverclassname}")    public void tdriverclass(string driverclass) {        this.driverclass = driverclass;    }    public string geturl() {        return url;    }    @value("${jdbc.url}")    public void turl(string url) {        this.url = url;    }    public string geturname() {        return urname;    }    // @value("$(jdbc.urname)")    @value("${jdbc.urname}")    public void turname(string urname) {        this.urname = urname;    }    public string getpassword() {        return password;    }    @value("${jdbc.password}")    public void tpassword(string password) {        this.password = password;    }    @override    public string tostring() {        return "mydatasource [driverclass=" + driverclass + ", url=" + url + ", urname=" + urname + ", password=" + password + "]";    }}
<?xml version="1.0" encoding="utf-8"?><beans xmlns="/d/file/titlepic/"    xmlns:xsi="/d/file/titlepic/xmlschema-instance"    xmlns:p="http://www.springframework.org/schema/p"    xmlns:context="/d/file/titlepic/"    xsi:schemalocation="http://www.springframework.org/schema/beans /d/file/titlepic/spring-beans.xsd        http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.3.xsd">    <!-- 扫描的基包 -->    <context:component-scan ba-package="com.xgj.spel.annotation"/>    <!-- 加载外部properties文件 -->    <context:property-placeholder location="classpath:mysql/db_mysql.properties"/>  </beans>

db_mysql.properties

jdbc.driverclassname=com.mysql.jdbc.driverjdbc.url=jdbc:mysql://localhostmba多少钱:3306/artisanjdbc.urname=artisanjdbc.password=artisan
package com.xgj.spel.annotation;import org.junit.test;import org.springframework.context.application南半球context;import org.springframework.context.support.classpathxmlapplicationcontext;public class testca {    @test    public void test() {        string configurationlocation = "com/xgj/spel/annotation/beans_anno.xml";        applicationcontext ctx = new classpathxmlapplicationcontext(configurationlocation);        mydatasource mydatasource = (mydatasource) ctx.getbean("mydatasource");        system.out.println(mydatasource);        system.out.println("driverclassname:" + mydatasource.getdriverclass());        system.out.println("url:" + mydatasource.geturl());        system.out.println("urname:" + mydatasource.geturname());        system.out.println("password:" + mydatasource.getpassword());    }}

运行结果

2018-04-07 23:37:11,409 info [main] (abstractapplicationcontext.java:583) – refreshing org.springframework.context.support.classpathxmlapplicationcontext@761df304: startup date [sat apr 07 23:37:11 bot 2018]; root of context hierarchy
2018-04-07 23:37:11,552 info [main] (xmlbeandefinitionreader.java:317) – loading xml bean definitions from class path resource [com/xgj/spel/annotation/beans_anno.xml]
mydatasource [driverclass=com.mysql.jdbc.driver, url=jdbc:mysql://localhost:3306/artisan, urname=artisan, password=artisan]
driverclassname:com.mysql.jdbc.driver
url:jdbc:mysql://localhost:3306/artisan
urname:artisan
password:artisan

以上为个人经验,希望能给大家一个参考,也希望大家多多支持www.887551.com。

本文发布于:2023-04-05 01:40:15,感谢您对本站的认可!

本文链接:https://www.wtabcd.cn/fanwen/zuowen/383056db8fbf2c4142fc4b0e5f429a3e.html

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。

本文word下载地址:使用Spring Expression Language (SpEL)全面解析表达式.doc

本文 PDF 下载地址:使用Spring Expression Language (SpEL)全面解析表达式.pdf

标签:表达式   属性   方法   对象
相关文章
留言与评论(共有 0 条评论)
   
验证码:
Copyright ©2019-2022 Comsenz Inc.Powered by © 专利检索| 网站地图