到目前为止我们为Bean的属性和构造器参数装配的所有东西都是在Sping的xml文件中静态定义的。但是如果我们为属性装配的值只又在运行的时期才能知道,如何实现?
Spring3中引入了Spring表达式语言:SpEL装配Bean方式,它通过运行期执行的表达式将值装配到Bean的属性或构造器参数中。
一.SpEL的基本原理
SqEL表达式的首要目标是通过计算获取某个值。最简单的SqEL求值或许是对字面值,Bean的属性或者某个类的常量进行求值。
(1)字面值
<property name="count" value="{5}"/>
#{}会提示Spring这个标记里面的内容是SpEL表达式,同时它们还可以与非SqEL表达式的值混用:
<span style="font-size:18px;"><property name="age" value="The value is #{22}"/></span>
String类型的字面值可以使用单引号或者双引号作为字符串的定界符。
<span style="font-size:18px;"><property name="name" value='#{"spring"}'/></span>
(2)引用Bean,Properties和方法
SqEL表达式能做的另一个基本事情是通过ID引用其他Bean。例如:我们需要在SqEL表达式中通过使用BeanID将一个Bean装配到另一个Bean属性中:
<span style="font-size:18px;"><property name="instrument" value="#{piano}"/> </span>
这里我们使用SqEL将一个ID为piano的Bean装配到了instrument属性中,当然我们可以不用SqEL而使用ref属性。
但是我们可以使用SqEl做更有趣的事情,我们可以调用piano的方法以及属性:
<span style="font-size:18px;"><property name="reinstrument" value="#{piano.replay()}"></property></span>
同样我们也可以调用piano的属性:例如我们返回英文歌曲名字,这里我们返回的
<span style="font-size:18px;"> <property name="song" value="#{piano.song?.toUpperCase()}"></property></span>
使用?.运算符是因为可以确保左边项不会为Null,如果song属性的值为null,SqEl将不会在调用该属性。
(3)操作类
在SqEL中使用T()运算符会调用类作用域的方法和常量例如:
<span style="font-size:18px;"><property name="num0" value="#{T(java.lang.Math).PI}"/>
<property name="num1" value="#{T(java.lang.Math).random() }"/></span>
二.在SqEL值上执行操作
SqEL提供了多种运算符,可以进行表达式求值:
Spring EL 支持大多数的数学操作符、逻辑操作符、关系操作符。
1.关系操作符
包括:等于 (==, eq),不等于 (!=, ne),小于 (<, lt),,小于等于(<= , le),大于(>, gt),大于等于 (>=, ge)
2.逻辑操作符
包括:and,or,and not(!)
3.数学操作符
包括:加 (+),减 (-),乘 (*),除 (/),取模 (%),幂指数 (^)。
(1)使用SqEL进行数值运算:
<property name="num0" value="#{T(java.lang.Math).PI+3.0}"/>
(2)使用SqEL进行比较值:
<property name="falg" value="#{T(java.lang.Math).random() == 1.000}"/>
(3)使用SqEL进行逻辑表达式:
<property name="falg" value="#{T(java.lang.Math).random() == 1.000 and T(java.lang.Math).PI > 3.0}"/>
(4)条件表达式:
<property name="instrument" value="#{piano.song == 'beijing'?piano:violino}"></property>
三.在SqEL中筛选集合
SqEL同样具有基于属性值来过滤集合成员的能力,SqEL还可以充集合的成员中提取某些属性放到一个新的集合中。
这里我们定义了一个City类:
package com.entity;
public class City {
<span style="white-space:pre"> </span>private String name;
<span style="white-space:pre"> </span>private String state;
<span style="white-space:pre"> </span>private int popluation;
<span style="white-space:pre"> </span>private City choseCity;
<span style="white-space:pre"> </span>public City getChoseCity() {
<span style="white-space:pre"> </span>return choseCity;
<span style="white-space:pre"> </span>}
<span style="white-space:pre"> </span>public void setChoseCity(City choseCity) {
<span style="white-space:pre"> </span>this.choseCity = choseCity;
<span style="white-space:pre"> </span>name = choseCity.getName();
<span style="white-space:pre"> </span>state=choseCity.getState();
<span style="white-space:pre"> </span>popluation=choseCity.getPopluation();
<span style="white-space:pre"> </span>}
<span style="white-space:pre"> </span>public String getName() {
<span style="white-space:pre"> </span>return name;
<span style="white-space:pre"> </span>}
<span style="white-space:pre"> </span>public void setName(String name) {
<span style="white-space:pre"> </span>this.name = name;
<span style="white-space:pre"> </span>}
<span style="white-space:pre"> </span>public String getState() {
<span style="white-space:pre"> </span>return state;
<span style="white-space:pre"> </span>}
<span style="white-space:pre"> </span>public void setState(String state) {
<span style="white-space:pre"> </span>this.state = state;
<span style="white-space:pre"> </span>}
<span style="white-space:pre"> </span>public int getPopluation() {
<span style="white-space:pre"> </span>return popluation;
<span style="white-space:pre"> </span>}
<span style="white-space:pre"> </span>public void setPopluation(int popluation) {
<span style="white-space:pre"> </span>this.popluation = popluation;
<span style="white-space:pre"> </span>}
<span style="white-space:pre"> </span>
<span style="white-space:pre"> </span>public void write(){
<span style="white-space:pre"> </span>System.out.println("name="+name+",state="+state+",popluation="+popluation);
<span style="white-space:pre"> </span>}
}
我们使用<util:list>元素在Spring中配置了一个包含City对象的List集合:
<util:list id="cities">
<bean class="com.entity.City"
p:name="敦化" p:state="吉林省" p:popluation="1000"/>
<bean class="com.entity.City"
p:name="北京" p:state="北京市" p:popluation="20000"/>
</util:list>
(1)访问集合成员:
<bean id="cityTest" class="com.entity.City">
<property name="choseCity" value="#{cities[0]}"/>
</bean>
这里的测试类:
package com;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import com.entity.City;
import com.entity.sqEl;
public class springTest {
public static void main(String[] args) {
ApplicationContext cxt=new ClassPathXmlApplicationContext(
"classpath:/spring/spring.xml");
City city=(City) cxt.getBean("cityTest");
city.write();
}
}