您好,欢迎访问三七文档
当前位置:首页 > IT计算机/网络 > 数据库 > Spring_Spring表达式语言(SpEL)
8.Spring表达式语言(SpEL)8.1介绍Spring表达式语言(简称SpEl)是一个支持查询和操作运行时对象导航图功能的强大的表达式语言.它的语法类似于传统EL,但提供额外的功能,最出色的就是函数调用和简单字符串的模板函数。尽管有其他可选的Java表达式语言,如OGNL,MVEL,JBossEL等等,但Spel创建的初衷是了给Spring社区提供一种简单而高效的表达式语言,一种可贯穿整个Spring产品组的语言。这种语言的特性应基于Spring产品的需求而设计。虽然SpEL引擎作为Spring组合里的表达式解析的基础,但它不直接依赖于Spring,可独立使用。为了整合,许多在本章使用SpEL例子就好像它是一个独立的表达式语言。这就需要创建一些引导如解析器这样的基础构造类。大多数Spring用户将不再需要处理这些基础构建,而是仅将作者表达的字符串进行解析。一个传统的使用例子是集成SpEL去创建XML或者定义Bean的注解,可以选择这里看到表达式支持定义bean.本章讲介绍SpEL的API,其语言语法的特点。在几个地方,Inventor和Inventor’sSociety类被用做表达式解析的目标对象。这些类声明和使用数据一直贯穿本章结尾。8.2功能概述表达式语言支持以下功能文字表达式布尔和关系运算符正则表达式类表达式访问properties,arrays,lists,maps方法调用关系运算符参数调用构造函数Bean引用构造Array内嵌lists内嵌maps三元运算符变量用户定义的函数集合投影集合筛选模板表达式8.3使用Spring的表达接口表达式求值本节介绍了简单的使用SpEL表达语言。完整的语言参考可以在语言参考一节中找到下面的代码使用SpELAPI来解析文本字符串表达式HelloWorld.ExpressionParserparser=newSpelExpressionParser();Expressionexp=parser.parseExpression('HelloWorld');Stringmessage=(String)exp.getValue();消息变量的值是简单的“helloworld”。该SpEL类和接口,你最有可能使用的是org.springframework.expression以及它的子包和spel.support。接口ExpressionParser负责解析表达式字符串。这个正则字符串例子是通过单引号扩起来的一个字符串排版声明。接口Expression负责解析之前被定义的字符串表达式SpEL支持很多功能特性,如调用方法,访问属性,调用构造函数。作为方法调用的一个例子,我们调用字符串的“CONCAT”的方法。ExpressionParserparser=newSpelExpressionParser();Expressionexp=parser.parseExpression('HelloWorld'.concat('!'));Stringmessage=(String)exp.getValue();结果将是HelloWorld!作为调用JavaBean属性的一个例子,String属性“Bytes”在下面被调用了。ExpressionParserparser=newSpelExpressionParser();//invokesgetBytes()Expressionexp=parser.parseExpression('HelloWorld'.bytes);byte[]bytes=(byte[])exp.getValue();SpEL还支持使用标准的“.”符号,即嵌套属性prop1.prop2.prop3和属性值的设置公共字段也可被访问。ExpressionParserparser=newSpelExpressionParser();//invokesgetBytes().lengthExpressionexp=parser.parseExpression('HelloWorld'.bytes.length);intlength=(Integer)exp.getValue();字符串的构造函数的调用被一个巧妙的字符代替了。ExpressionParserparser=newSpelExpressionParser();Expressionexp=parser.parseExpression(newString('helloworld').toUpperCase());Stringmessage=exp.getValue(String.class);注意这里用到一般方法publicTTgetValue(ClassTdesiredResultType).使用这种方法没必要实例化表达式的值的结果类型.如果该值不能被转换为类型T或使用已注册的类型转换器转换,那么一个EvaluationException会抛出。SpEL比较常见的用途是针对一个特定的对象实例(称为rootobject)提供被解析的表达式字符串.这里有两种选择andwhichtochoosedependsonwhethertheobjectagainstwhichtheexpressionisbeingevaluatedwillbechangingwitheachcalltoevaluatetheexpression.在下面的例子中,我们检索一个Inventor类的实例的name的属性。//CreateandsetacalendarGregorianCalendarc=newGregorianCalendar();c.set(1856,7,9);//Theconstructorargumentsarename,birthday,andnationality.Inventortesla=newInventor(NikolaTesla,c.getTime(),Serbian);ExpressionParserparser=newSpelExpressionParser();Expressionexp=parser.parseExpression(name);EvaluationContextcontext=newStandardEvaluationContext(tesla);Stringname=(String)exp.getValue(context);在最后一行,该字符串变量name的值将被设定为“NikolaTesla”。类StandardEvaluationContext是可以指定哪些对象的“name”属性将被解析。如果rootobject不太可能改变.,就可以简单地在评估上下文中设置一次。如果rootobject反复变化,它可以在每次调用getValue,如接下来的例子说明:/CreateandsetacalendarGregorianCalendarc=newGregorianCalendar();c.set(1856,7,9);//Theconstructorargumentsarename,birthday,andnationality.Inventortesla=newInventor(NikolaTesla,c.getTime(),Serbian);ExpressionParserparser=newSpelExpressionParser();Expressionexp=parser.parseExpression(name);Stringname=(String)exp.getValue(tesla);在这种情况下,inventortesla已直接应用到getValue和表达式计算基础架构创建和管理一个默认的解析环境在内部-它不要求再次解析。StandardEvaluationContext是相对昂贵的构造和在重复使用它建立缓存的状态,使得后续的解析将会变得更快.出于这个原因,它将尽可能的更好的缓存和重用这些对象,而不是建立一个新的每个表达式求值。在某些情况下,它可以是理想的使用配置解析上下文,但仍然在每次调用getValue提供不同的rootobject。getValue允许既要在同一个调用中指定。在这些情况下对rootobject通过调用要考虑到覆盖任何(这可能为空)在解析范围内的指定。[注意]在SpEL的独立使用的时候,需要创建parser,parseexpressions,同时可能需要提供解析的context和rootcontextobject。然而,更常见的用法是只提供一个SpEL表达式字符串作为配置文件的一部分,例如,对于Spring的bean或SpringWebFlow的定义。在这种情况下,解析器求值的context,rootobject和所有预定义变量都设置了隐式,没有什么要用户去指定了,除了声明表达式.作为最后一个例子,使用了一个boolean运算符去调用inventorobject在前面的例子中。Expressionexp=parser.parseExpression(name=='NikolaTesla');booleanresult=exp.getValue(context,Boolean.class);//evaluatestotrue8.3.1EvaluationContext接口当计算表达式解析properties,methods,fields,并帮助执行类型转换,使用接口EvaluationContext这是一个开箱即用的实现,StandardEvaluationContext,使用反射来操纵对象,缓存java.lang.reflect的Method,Field,和Constructor实例提高性能。该StandardEvaluationContext是你可以指定rootobject通过使用setRootObject()或传递rootobject到构造函数.你也可以指定变量和函数使用方法'的setVariable()和`registerFunction()的表达式。变量和函数的使用将在变量中介绍,同时函数.StandardEvaluationContext也是在那里你可以自定义的注册ConstructorResolvers,MethodResolvers,andPropertyAccessorstoextendhowSpELevaluatesexpressions.请参见这些类的Javadoc获得更多信息。类型转换默认情况下,SpEL使用Spring-core的转换服务(org.springframework.core.convert。ConversionService)。这种转换的服务许多转换器内置了常用的转换,但也完全可扩展类型之间的定制的转换可以增加。此外,它拥有的关键能力是泛型感知。这意味着,当与通用类型的工作表达式,SpEL将尝试转换他遇到的维持对任何对象类型的正确性这做法是什么意思呢?假设分配,使用的setValue()',正在使用以设置一个`List属性。该属性的类型实际上是ListBoolean。SpEL将认识到,需要在列表中的元素之前,必须转换成Boolean一个简单的例子:classSimple{publicListBooleanbooleanList=newArrayListBoolean();}Simplesimple=newSimple();simple.booleanList.add(true);StandardEvaluationContextsimpleContext=newStandardEvaluationContext(simple);//falseispassedinhereasastring.SpELandtheconversionservicewill//correctlyrecognizethatitneedstobeaBooleanandconvertitpa
本文标题:Spring_Spring表达式语言(SpEL)
链接地址:https://www.777doc.com/doc-2859809 .html