Spring 3.0 创建了一种新的方式用以配置对象的注入(set注入或者构造参数注入)–SpEL
一、基本特性:
使用#{…}作为定界符,所有的大括号中的字符都将被认定为是SpELl
1、字面量的表示:
<property name="count" value="#{5}"/>
2、小数:
<property name="count" value="#{5.5}"/>
3、科学计数法:
<property name="capacity" value="#{1e4}"/>
4、String 可以使用单引号或者双引号作为字符串的定界符号:
<property name="name" value="#{'tom'}"/> 或者
<property name="name" value='#{"tom"}'/> 视外部情况而定
5、Boolean:
<property name="enabled" value="#{false}"/>
二、引用Bean属性和方法
1、引用其他对象
<bean id="obj1" value="com.xxx.xxx.Xxx"/>
<bean id="obj2" value="com.xxx.xxx.Xxx2">
<property name="instrument" value="#{obj1}"/>
</bean>
通过id:”obj1”将对象注入到instrument属性中,这与下面的配置是一样的:
<property name="instrument" ref="obj1"/>
2、引用其他对象的属性:
<bean id = "obj" class="com.xxx.xxx.Xxx">
<property name="song" value="#{kenny.song}"/>
</bean>
kenny 是Bean id 而song是属性的名字,这样配置就如同我们写了如下代码
Xxx obj= new Xxx();
obj.setSong(kenny.getSong());
3、调用其他的方法
<property name ="song" voalue="songSelector.selectSong()"/>
调用了Beanld为”songSelector”的对象的selectSong()方法,并将返回值注入到song属性中,或者还可以脸是操作。如下:
<property name="song" value="songSelector.selectSong().toUpperCase()"/>
如果songSelector.selectSong()返回null的还会抛出异常,为了避免,我们要使用?.表达式。这样如果songSelector.selectSong()为null就不会再调用后面的方法了。如下:
<property name="song" value="songSelector.selectSong()?.toUpperCase()"/>
4、调用静态方法
我们已经知道如何通过一个对戏那个调用它的方法了,但是如何调用一个静态方法呢?用T()。
它将返回一个Class object
然后我们再调用相应的方法即可:
<property name="multiplier" value="T(java.lang.Math).PI"/>
SpEL支持的运算符号
1、算数运算符:+、-、*、/、%、^
<property name="adjustedAmount" value="#{counter.total+42}"/>
<property name="adjustedAmount" value="#{counter.total-20}"/>
<property name="circumference" value="#{2*T(java.lang.Math).PI*circle.redius}"/>
<property name="average" value="#{counter.total/counter.count}"/>
<property name="remainder" value="#{{counter.total%counter.count}"/>
<property name="area" value="#{T(java.lang.Math).PI*circle.radius^2}"/>
加号还可以用作字符串连接:
<property name="fullName" value="#{performer.firstName + ' '+performer.lastName}"/>
2、比较运算符:< , > ,== , <= , >= ,lt ,gt, eq, le ,ge
<property name="equal" value="#{counter.total==100}"/>
不可以使用< 和 > 号,应为在xml中它有特殊含义,我们使用lt和gt代替
<property name="hasCapacity" value="#{counter.total le 1000}"/>
3、逻辑运算符号 and , or , not, !
<property name="largeCircle" value="#{shape.kind=='circle' and shape.perimeter gt 1000}"/>
<property name="outOfStock" value="#{!product.available}"/>
<property name="outOfStock" value="#{not product.available}"/>
**4、if-else 运算符 : ?:(ternary), ?:(Elvis)
最基本的?:(如同使用EL表达式):**
<property name="instrument" value="#{songSelector.selecSong()=='Jingle Bells' ? piano : 'Jingle Bells '}"/>
变体的 ?:
<property name="song" value="#{ kenny.song!=null ? kenny.song : 'Greensleeves'}"/>
优化后:<property name="song" value="#{ kenny.song ? : 'Greensleeves'}"/>
显然,优化后的书写更为简洁
5、正则表达式:matches
<property name="validEmail" value="#{admin.email matches '[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\\.[a-zA-Z]{2,4}'}"/>
表达式返回逻辑值,如果匹配返回true,否则返回false
SpEL对集合的支持
有实体类如下:
package com.it.items;
public class Person{
private String name;
private int age;
}
xml中有如下定义
<util:list id = "persons">
<bean class="com.it.items" p:name="zhangsan" p:age="20"/>
<bean class="com.it.items" p:name="lisi" p:age="22"/>
<bean class="com.it.items" p:name="wangwu" p:age="30"/>
<bean class="com.it.items" p:name="laoda" p:age="28"/>
</util:list>
1、获取Collection中的某个对象
通过下标访问,如下:
<property name="person" value="#{persons[3]}"/>
这样就能得到name为laoda的person对象。(下标从0开始)
下标还可以通过变量来指定:
<property name="person" value="#{persons[T(java.lang.Math).reandom()*persons.size()]}"/>
如果是从Map中获取,可指定key值,
<property name="person" value="#{persons['key']}"/>
也可以通过key访问properties的值,
<util:properties id = "settings" location="classpath:settings.properties"/>
<property name="accessToken" value="#{settings['twitter.accessToken']}"/>
可以通过下标访问 systemEnvironment 和 SystemProperties 中的值,
<property name="homePath" value="#{systemEnvironment['HOME']}"/>
如果在 jre 运行时配置了-Dapplication.home=/etc/myapp,我们可以通过如下方式访问
<property name="homePath" value="#{systemProperties['application.home']}"/>
通过小标获取String 串种的某个字符
'This is a test'[8]
2、获取Collection中的子集,通过条件筛选(获取到的是一个新的Collection对象)
筛选子集:
<property name="bigCities" value="#{persons.?[age gt 20]}"/>
获取第一个(.^[]):
<property name="aBigCity" value="#{persons.^[age gt 20]}"/>
获取最后一个(.$[])
<property name="aBigCity" value="#{persons.$[age gt 20]}"/>
3、集合的投影(.![])
获取name组成的列表,
<property name="cityNames" value="#{persons.![name]}"/>
也可以获取多列
<property name="cityNames" value="#{persons.![name + ', ' + age]}"/>
4、将投影和筛选结合,
<property name="cityNames" value="#{persons.?[age gt 20].![name +', ' + state]}"/>
本文只作为初学者笔记参考,勿喷