在表达式里面所有的操作都是可以变量的形式出现的,但是一般情况下只会出现在基本的操作之中.
范例:观察变量的定义
package cn.zwb.demo;
import org.springframework.expression.EvaluationContext;
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 TestELSimple {
public static void main(String[] args) {
ExpressionParser parpser = new SpelExpressionParser();
Expression exp = parpser.parseExpression("#myvar");
EvaluationContext context=new StandardEvaluationContext();
context.setVariable("myvar", "hello");
System.out.println(exp.getValue(context));
}
}
如果要想设置变量则必须依靠"EvaluationContext"类完成,而在"StandardEvaluationContext"子类的方法上也可以接收一个变量:public StandardEvaluationContext(Object rootObject),这个构造方法表示的是设置根变量的内容.整个变量体系之中会存在有一个#root的根变量.
范例:观察根变量的操作
package cn.zwb.demo;
import org.springframework.expression.EvaluationContext;
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 TestELSimple {
public static void main(String[] args) {
ExpressionParser parpser = new SpelExpressionParser();
Expression exp = parpser.parseExpression("#root");
EvaluationContext context=new StandardEvaluationContext("zwb");
System.out.println(exp.getValue(context));
}
}
现在的程序并没有针对于根变量调用"context.setVariable("root", "zwb");"那么也就是说根变量通过构造方法传递到了程序之中;
实际上设置的变量可以做一些基础的表达式的操作处理.
范例:进行比较
package cn.zwb.demo;
import org.springframework.expression.EvaluationContext;
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 TestELSimple {
public static void main(String[] args) {
ExpressionParser parpser = new SpelExpressionParser();
Expression exp = parpser.parseExpression("#root =='mldn'?'你好':'大家好'");
EvaluationContext context=new StandardEvaluationContext("zwb");
System.out.println(exp.getValue(context));
}
}
可能大部分情况下见到最多的都是使用一些自定义的变量进行使用.
实际上如果进一步去研究表达式可以发现,它还可以针对于方法进行引用操作.
那么下面打算将"Integer.parseInt()"方法设置为"myInt()"的引用.
范例:实现方法引用
package cn.zwb.demo;
import java.lang.reflect.Method;
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 TestELSimple {
public static void main(String[] args) throws NoSuchMethodException, SecurityException {
ExpressionParser parpser = new SpelExpressionParser();
//找到Integer,parseInt()这个操作方法的对象
Method method=Integer.class.getMethod("parseInt", String.class);
Expression exp = parpser.parseExpression("#myInt('123')");
//利用EvaluationContext类进行方法的引用注册
StandardEvaluationContext context=new StandardEvaluationContext("zwb");
context.registerFunction("myInt", method);
System.out.println(exp.getValue(context));
}
}
就相当于使用myInt方法在表达式之中就相当于调用Integer.parseInt()方法实现了字符串与int数据的互相转换操作
实际上除了以上的基本调用之外,还可以继续利用表达式的特征调用类中的属性,以Date类为例,有一个方法叫getTime(),此方法可以将Date类型数据变为long型数据.
范例:调用属性
package cn.zwb.demo;
import java.lang.reflect.Method;
import java.util.Date;
import org.springframework.expression.EvaluationContext;
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 TestELSimple {
public static void main(String[] args) throws NoSuchMethodException, SecurityException {
ExpressionParser parpser = new SpelExpressionParser();
Method method=Integer.class.getMethod("parseInt", String.class);
Expression exp = parpser.parseExpression("time");
EvaluationContext context=new StandardEvaluationContext(new Date());
System.out.println(exp.getValue(context));
}
}
此时将java.util.Date类型的对象设置到了根变量中,所以一旦表达式之中出现了"time"单词,就表示要多用用getTime()方法,需要特别提醒的是,这个时候表达式是不区分大小写,
Expression exp = parpser.parseExpression("Time");
但是这种调用本事是有风险的,此时的调用必须有一个前提:根变量有内容,那么如果根变量为空呢?
范例:观察根变量为空的情况
package cn.zwb.demo;
import org.springframework.expression.EvaluationContext;
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 TestELSimple {
public static void main(String[] args) throws NoSuchMethodException, SecurityException {
ExpressionParser parpser = new SpelExpressionParser();
Expression exp = parpser.parseExpression("time");
EvaluationContext context=new StandardEvaluationContext();
System.out.println(exp.getValue(context));
}
}
Exception in thread "main" org.springframework.expression.spel.SpelEvaluationException:
EL1007E:(pos 0): Property or field 'time' cannot be found on null
如果此时使用的此类取得属性信息,那么它是不能够进行访问的,因为根变量为空就会出现异常,那么这个时候最好的解决方式不是增加什么判断,而是使用Groovy安全导航操作,利用Groovy安全运算符避免空异常
范例:使用"?."访问属性
package cn.zwb.demo;
import org.springframework.expression.EvaluationContext;
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 TestELSimple {
public static void main(String[] args) throws NoSuchMethodException, SecurityException {
ExpressionParser parpser = new SpelExpressionParser();
Expression exp = parpser.parseExpression("#root?.time");
EvaluationContext context=new StandardEvaluationContext();
System.out.println(exp.getValue(context));
}
}
如果此时根变量的内容为空,那么返回的就是"null",如果现在不为空,那么就可以返回具体的操作内容.
以上所有的操作变量都是在程序之中直接定义的,那么也可以引用applicationContext.xml里面的内容,
范例:引用配置中的变量
●定义一个Massge类,里面只有一个属性,同时提供好setter和getter操作;
package cn.zwb.vo;
public class Message {
private String info;
public String getInfo() {
return info;
}
public void setInfo(String info) {
this.info = info;
}
}
●随后在applicationContext.xml里面配置这个类对象,
<bean id="msg" class="cn.zwb.vo.Message">
<property name="info" value="hello"></property>
</bean>
现在msg对象中的info属性里面是包含有配置内容的,随后希望可以在表达式里面可以引用这部分内容
●引用配置内容,如果要进行导入外部配置,使用"@名称.方法()"
package cn.zwb.demo;
import org.springframework.context.ApplicationContext;
import org.springframework.context.expression.BeanFactoryResolver;
import org.springframework.context.support.ClassPathXmlApplicationContext;
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 TestApplication {
public static void main(String[] args) throws NoSuchMethodException, SecurityException {
ApplicationContext ctx =new ClassPathXmlApplicationContext("ApplicationContext.xml");
ExpressionParser parpser = new SpelExpressionParser();
Expression exp = parpser.parseExpression("@msg.getInfo()");
StandardEvaluationContext context=new StandardEvaluationContext();
//将配置文件的内容读取交给上下文
context.setBeanResolver(new BeanFactoryResolver(ctx));
System.out.println(exp.getValue(context));
}
}
就相当于此时,所有的外部配置的对象可以直接在表达式之中使用了,并且利用表达式的语法调用对象的所提供的方法.