有两种用法辅助我们从特定的上下文获取 特定的expression取值,具体选择哪种取决于你每次evaluate the expression时对象是否会发生改变。来看看两种代码:
/**
* The StandardEvaluationContext is relatively expensive to construct and during repeated usage
* it builds up cached state that enables subsequent expression evaluations to be performed more quickly.
* For this reason it is better to cache and reuse them where possible, rather than construct a new one for each expression evaluation.
*/
@Test
public void run5() {
GregorianCalendar cal = new GregorianCalendar();
cal.set(1856, 7, 9);
Inventor inventor = new Inventor("Nicolas Tesla", cal.getTime(), "serbian");
SpelExpressionParser parser = new SpelExpressionParser();
Expression expression = parser.parseExpression("name");
// 利用目标对象(root object)构造一个context。开销相对较高,建议仅用于不常改变的对象。
EvaluationContext evaluationContext = new StandardEvaluationContext(inventor);
inventor.setName("Newton"); // 还是会起作用
// 从指定的context中获取本表达式对应的值。
String value = (String) expression.getValue(evaluationContext);
System.out.println(value);
}
// 如果root object可能发生改变,不建议使用其创建一个context,因为开销较高。应该如下:
@Test
public void run6() {
GregorianCalendar cal = new GregorianCalendar();
cal.set(1856, 7, 9);
Inventor inventor = new Inventor("Nicolas Tesla--", cal.getTime(), "serbian");
SpelExpressionParser parser = new SpelExpressionParser();
Expression expression = parser.parseExpression("name");
// 直接从目标对象中获取本表达式对应的值。内部还是会创建一个context。
// the expression evaluation infrastructure creates and manages a default evaluation context internally
String value = (String) expression.getValue(inventor);
System.out.println(value);
inventor.setName("Newton"); // 也起作用了
value = (String) expression.getValue(inventor);
System.out.println(value);
}
这里的关键在于:Expression是从指定的上下文中获取相应的内容。粗略的说,Expression指定了要获取的property name,但还需要指定从什么地方获取该property value -- 是从EvaluationContext中获取的。
上面两个案例,run5() 是用目标对象(inventor)直接构造了一个StandardEvaluationContext,以供Expression从中获取值; run6() 则是让Expression直接从目标对象(inventor)中获取值 --但实际上内部还是构造了一个EvaluationContext。
二者的不同之处在于StandardEvaluationContext开销较大。
The StandardEvaluationContext is relatively expensive to construct and during repeated usage,
it builds up cached state that enables subsequent expression evaluations to be performed more quickly.
For this reason it is better to cache and reuse them where possible, rather than construct a new one for each expression evaluation.
In standalone usage of SpEL there is a need to create the parser,
parse expressions and perhaps provide evaluation contexts and a root context object.
However, more common usage is to provide only the SpEL expression string as part of a
configuration file, for example for Spring bean or Spring Web Flow definitions. In this case,
the parser, evaluation context, root object and any predefined variables are all set up
implicitly, requiring the user to specify nothing other than the expressions.
EvaluationContext 的开销一般比较大,一般用于context不太变动的情况下
网友评论