专栏首页杂烩spring的spel 转

spring的spel 转

 Spring 3.0 创建了一种新的方式用以配置对象的注入(set注入或者构造参数注入),它便是SpEL (Spring Expression Language)下面我们一一做一介绍。

▲基础特性

——SpEL使用#{…}作为定界符,所有在大框号中的字符都将被认为是SpEL.

——1、 字面量的表示 

  1>整数

  1. <property name="count" value="#{5}"/>

 2>小数

  1. <property name="frequency" value="#{89.7}"/>

  3>科学计数法

  1. <property name="capacity" value="#{1e4}"/>

 4>String可以使用单引号或者双引号作为字符串的定界符号。

  1. <property name="name" value="#{'Chuck'}"/>
  2. <property name='name' value='#{"Chuck"}'/>

 5>Boolean

  1. <property name="enabled" value="#{false}"/>

——2、 引用Bean,属性和方法

 1>引用其他对象

  1. <bean id=”saxophone” value=”com.xxx.xxx.Xxx”/>
  2. <bean ..>
  3. .  
  4. <property name="instrument" value="#{saxophone}"/>
  5. .  
  6. <bean/>

通过id:“saxophone”将对象注入到instrument属性中,这与下面的配置是一样的:

  1. <property name="instrument" ref="saxophone"/>

  2> 引用其他对象的属性

  1. <bean id="carl"
  2. class="com.springinaction.springidol.Instrumentalist">
  3. <property name="song" value="#{kenny.song}" />
  4. </bean>

kenny是Bean Id 而 song是属性的名字,这样配置就如同我们写了如下的代码

  1. Instrumentalist carl = new Instrumentalist();  
  2. carl.setSong(kenny.getSong());  

 3>调用其他方法

  1. <property name="song" value="songSelector.selectSong()"/>

调用了BeanId为“songSelector”的对象的selectSong()方法,并将返回值注入到song属性中。或者还可以链式操作。如下:

  1. <property name="song" value="songSelector.selectSong().toUpperCase()"/>

如果songSelector.selectSong()返回null的还会抛出异常,为了避免我们要使用?.表达式。这样如果songSelector.selectSong()为null就不会再调用后面的方法了。如下

  1. <property name="song" value="songSelector.selectSong()?.toUpperCase()"/>

 4>调用静态方法

我们已经知道如何通过一个对象调用它的方法了,但是如何调用一个静态方法呢?用T()。它将返回一个 Class object 然后我们再调用相应的方法即可: 

  1. <property name="multiplier" value="T(java.lang.Math).PI"/>

▲SpEL支持的运算符号 ——1、算数运算符:+, -, *, /, %, ^

  1. <property name="adjustedAmount" value="#{counter.total + 42}"/>
  2. <property name="adjustedAmount" value="#{counter.total - 20}"/>
  3. <property name="circumference" value="#{2 * T(java.lang.Math).PI * circle.radius}"/>
  4. <property name="average" value="#{counter.total / counter.count}"/>
  5. <property name="remainder" value="#{counter.total % counter.count}"/>
  6. <property name="area" value="#{T(java.lang.Math).PI * circle.radius ^ 2}"/>

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

  1. <property name="fullName" value="#{performer.firstName + ' ' + performer.lastName}"/>

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

  1. <property name="equal" value="#{counter.total == 100}"/>

不可以使用<和>号,应为在xml中它有特殊的含义,我们使用lt和gt代替

  1. <property name="hasCapacity" value="#{counter.total le 100000}"/>

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

  1. <property name="largeCircle" value="#{shape.kind == 'circle' and shape.perimeter gt 10000}"/>
  2. <property name="outOfStock" value="#{!product.available}"/>
  3. <property name="outOfStock" value="#{not product.available}"/>

——4、 If-else运算符:?: (ternary), ?: (Elvis)

〇最基本的 ?:(这如同我们在使用EL表达式语言):

  1. <property name="instrument" value="#{songSelector.selectSong() == 'Jingle Bells' ? piano : ' Jingle Bells '}"/>

〇变体的 ?:

 <property name="song" value="#{kenny.song != null ? kenny.song : 'Greensleeves'}"/>

上下两种是同一语义,但下面的明显简洁

  1. <property name="song" value="#{kenny.song ?: 'Greensleeves'}"/>

——5、 正则表达式:matches

  1. <property name="validEmail" value="#{admin.email matches '[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\\.[a-zA-Z]{2,4}'}"/>

表达式返回逻辑值,如果匹配返回true,否则返回false

▲SpEL对集合的支持

——环境

有实体City定义如下:

  1. package com.habuma.spel.cities;  
  2. public class City {  
  3. private String name;  
  4. private String state;  
  5. private int population;  
  6. }  

Xml中有如下定义

  1. <util:list id="cities">
  2. <bean class="com.habuma.spel.cities.City"
  3. p:name="Chicago" p:state="IL" p:population="2853114"/>
  4. <bean class="com.habuma.spel.cities.City"
  5. p:name="Atlanta" p:state="GA" p:population="537958"/>
  6. <bean class="com.habuma.spel.cities.City"
  7. p:name="Dallas" p:state="TX" p:population="1279910"/>
  8. <bean class="com.habuma.spel.cities.City"
  9. p:name="Houston" p:state="TX" p:population="2242193"/>
  10. <bean class="com.habuma.spel.cities.City"
  11. p:name="Odessa" p:state="TX" p:population="90943"/>
  12. <bean class="com.habuma.spel.cities.City"
  13. p:name="El Paso" p:state="TX" p:population="613190"/>
  14. <bean class="com.habuma.spel.cities.City"
  15. p:name="Jal" p:state="NM" p:population="1996"/>
  16. <bean class="com.habuma.spel.cities.City"
  17. p:name="Las Cruces" p:state="NM" p:population="91865"/>
  18. </util:list>

——1、 获取Collection中的某个对象

〇通过下标访问,如下:

  1. <property name="chosenCity" value="#{cities[2]}"/>

我们就会获得population为"1279910"的city(记住下标从0开始)

〇下标可以通过变量指定,如下:

  1. <property name="chosenCity" value="#{cities[T(java.lang.Math).random() * cities.size()]}"/>

〇如果是从Map中获得,可指定key值,如下

  1. <property name="chosenCity" value="#{cities['Dallas']}"/>

〇也可以通过key访问properties的值,如下

  1. <util:properties id="settings" location="classpath:settings.properties"/>
  2. <property name="accessToken" value="#{settings['twitter.accessToken']}"/>

〇可以通过下标访问systemEnvironment和SystemProperties中的值

  1. <property name="homePath" value="#{systemEnvironment['HOME']}"/>

〇如果在jre运行时配置了-Dapplication.home=/etc/myapp,我们可以通过如下方式访问

  1. <property name="homePath" value="#{systemProperties['application.home']}"/>

〇通过下标获取String串中的某个字符

  1. 'This is a test'[3]  

——2、获取Collection中的子集-通过条件筛选(注意新对象是一个新的Collection)

   1>筛选子集(.?[])

  1. <property name="bigCities" value="#{cities.?[population gt 100000]}"/>

   2>获取第一个(.^[])

  1. <property name="aBigCity" value="#{cities.^[population gt 100000]}"/>

   3>获取最后一个(.$[])

  1. <property name="aBigCity" value="#{cities.$[population gt 100000]}"/>

——3、集合的投影(.![])

 如果想获得所有城市的名称组成的列表,可用如下操作

  1. <property name="cityNames" value="#{cities.![name]}"/>

将返回"Chicago", "Atlanta", "Dallas"

也可以组合两个列,如下:

  1. <property name="cityNames" value="#{cities.![name + ', ' + state]}"/>

将返回"Chicago, IL", "Atlanta, GA", and "Dallas, TX".

—— 4、将投影和筛选结合

  1. <property name="cityNames" value="#{cities.?[population gt 100000].![name + ', ' + state]}"/>

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • spring集成activemq 原

    两个项目,一个生产者一个消费者,这里只贴出关键代码(队列模式和订阅模式),文章最后会附上项目地址,有需要的可以自行下载。项目访问地址http://localho...

    尚浩宇
  • SSM项目搭建之druid 原

    1) 可以监控数据库访问性能,Druid内置提供了一个功能强大的StatFilter插件,能够详细统计SQL的执行性能,这对于线上分析数据库访问性能有帮助。 

    尚浩宇
  • javamoledy使用异常 原

    将xml部分注释,依旧报错,发现MonitoringFilter依然在运行,推测可能这个版本实现了ServletContainerInitializer,自动注...

    尚浩宇
  • Java程序员的日常——SpringMVC+Mybatis开发流程、推荐系统

    今天大部分时间都在写业务代码,然后算是从无到有的配置了下spring与mybatis的集成。 SpringMVC+Mybatis Web开发流程 配置数据...

    用户1154259
  • Hadoop install

    XING辋
  • jdbc连接Mysql报错“java.sql.SQLException: Incorrect string value:。。。”的解决办法

    产生这种异常的原因在于,mysql中的utf8编码最多会用3个字节存储一个字符,如果一个字符的utf8 编码占用4个字节(最常见的就是ios中的emoji表情...

    飞奔去旅行
  • 基于SSM的数据库连接池框架druid的使用

    可以先去druid的官网下载jar:http://druid.io/downloads.html

    SmileNicky
  • druid简介与运用

    Druid首先是一个数据库连接池。Druid是目前最好的数据库连接池,在功能、性能、扩展性方面,都超过其他数据库连接池,包括DBCP、C3P0、BoneCP、P...

    Java架构师历程
  • Hive篇--搭建Hive集群

    Hive中搭建分为三中方式 a)内嵌Derby方式 b)Local方式 c)Remote方式 三种方式归根到底就是元数据的存储位置不一样。

    LhWorld哥陪你聊算法
  • 基于druid和spring的动态数据库以及读写分离

    spring与druid可以实现动态数据源,夸库查询,读写分离等功能。现在说一下配置:

    一笠风雨任生平

扫码关注云+社区

领取腾讯云代金券