1. SpEL简介
SpEL(Spring Expression Language),即Spring表达式语言,是比JSP的EL更强大的一种表达式语言。为什么要总结SpEL,因为它可以在运行时查询和操作数据,尤其是数组列表型数据,因此可以缩减代码量,优化代码结构。
2. SpEL 用法
SpEL有三种用法:
- 在注解@Value中
- 在XML配置中
- 在代码块中使用Expression。
2.1 @value
//@Value能修饰成员变量和方法形参
//#{}内就是表达式的内容
@Value("#{表达式}")
public String arg;
2.2 <bean>配置
<bean id="xxx" class="com.java.XXXXX.xx">
<!-- 同@Value,#{}内是表达式的值,可放在property或constructor-arg内 -->
<property name="arg" value="#{表达式}">
</bean>
2.3 Expression
import org.springframework.expression.Expression;
import org.springframework.expression.ExpressionParser;
import org.springframework.expression.spel.standard.SpelExpressionParser;
import org.springframework.expression.spel.support.StandardEvaluationContext;
public class SpELTest {
public static void main(String[] args) {
//创建ExpressionParser解析表达式
ExpressionParser parser = new SpelExpressionParser();
//表达式放置
Expression exp = parser.parseExpression("表达式");
//执行表达式,默认容器是spring本身的容器:ApplicationContext
Object value = exp.getValue();
/**如果使用其他的容器,则用下面的方法*/
//创建一个虚拟的容器EvaluationContext
StandardEvaluationContext ctx = new StandardEvaluationContext();
//向容器内添加bean
BeanA beanA = new BeanA();
ctx.setVariable("bean_id", beanA);
//setRootObject并非必须;一个EvaluationContext只能有一个RootObject,引用它的属性时,可以不加前缀
ctx.setRootObject(XXX);
//getValue有参数ctx,从新的容器中根据SpEL表达式获取所需的值
Object value = exp.getValue(ctx);
}
}
3.表达式语法
3.1 字面量赋值
<!-- 整数 -->
<property name="count" value="#{5}" />
<!-- 小数 -->
<property name="frequency" value="#{13.2}" />
<!-- 科学计数法 -->
<property name="capacity" value="#{1e4}" />
<!-- 字符串 #{"字符串"} 或 #{'字符串'} -->
<property name="name" value="#{'我是字符串'}" />
<!-- Boolean -->
<property name="enabled" value="#{false}" />
- 字面量赋值必须要和对应的属性类型兼容,否则会报异常。
- 一般情况下我们不会使用 SpEL字面量赋值,因为我们可以直接赋值
3.2 运算符
3.2.1算数运算符(+,-,*,/,%,^)
<!-- 3 -->
<property name="num" value="#{2+1}" />
<!-- 1 -->
<property name="num" value="#{2-1}" />
<!-- 4 -->
<property name="num" value="#{2*2}" />
<!-- 3 -->
<property name="num" value="#{9/3}" />
<!-- 1 -->
<property name="num" value="#{10%3}" />
<!-- 1000 -->
<property name="num" value="#{10^3}" />
3.2.2 字符串连接符:+
<!-- 10年3个月 -->
<property name="numStr" value="#{10+'年'+3+'个月'}" />
3.2.3 比较运算符:<(<),>(>),==,<=,>=,lt,gt,eq,le,ge
<!-- false -->
<property name="numBool" value="#{10<0}" />
<!-- false -->
<property name="numBool" value="#{10 lt 0}" />
<!-- true -->
<property name="numBool" value="#{10>0}" />
<!-- true -->
<property name="numBool" value="#{10 gt 0}" />
<!-- true -->
<property name="numBool" value="#{10==10}" />
<!-- true -->
<property name="numBool" value="#{10 eq 10}" />
<!-- false -->
<property name="numBool" value="#{10<=0}" />
<!-- false -->
<property name="numBool" value="#{10 le 0}" />
<!-- true -->
<property name="numBool" value="#{10>=0}" />
<!-- true -->
<property name="numBool" value="#{10 ge 0}" />
3.2.4 逻辑运算符:and,or,not,&&(&&),||,!
<!-- false -->
<property name="numBool" value="#{true and false}" />
<!-- false -->
<property name="numBool" value="#{true&&false}" />
<!-- true -->
<property name="numBool" value="#{true or false}" />
<!-- true -->
<property name="numBool" value="#{true||false}" />
<!-- false -->
<property name="numBool" value="#{not true}" />
<!-- false -->
<property name="numBool" value="#{!true}" />
3.2.5 条件运算符:?true:false
<!-- 真 -->
<property name="numStr" value="#{(10>3)?'真':'假'}" />
3.2.6 正则表达式:matches
<!-- true -->
<property name="numBool" value="#{user.email matches '[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+.[a-zA-Z]{2,4}'}" />
4.调用静态方法或静态属性
通过 T() 调用一个类的静态方法,它将返回一个 Class Object,然后再调用相应的方法或属性
<!-- 3.141592653589793 -->
<property name="PI" value="#{T(java.lang.Math).PI}" />