Spring Expression Language(SpEL,Spring表达式语言)是一种强大的支持运行时查询和操作对象导图功能的表达式语言。它的语法类似于传统的表达式语言,但在此基础上提供更多的功能,例如:函数调用和基本的字符串模板方法。
Spring表达式语言支持以下功能:
SpEL的类和接口位于org.springframework.expression包及其子包中,例如:spel.support。
ExpressionParser接口用来解析表达式字符串。
Expression接口用来计算表达式字符串。
当ExpressionParser.parseExpression(String expressionStr)和Expression.getValue(…)被调用的时候,ParseException和EvaluationException将分别被抛出。
EvaluationContext接口在计算表达式时被用来处理属性、方法、域,以及执行类型转换。 Spring对该接口提供了两种实现:
当SpEL可以获取和设置表达式中对象的值。在设置的时候,可能会发生类型转换,Spring表达式是支持这样的类型转换的。例如:
class Simple {
public List booleanList = new ArrayList();
}
Simple simple = new Simple();
simple.booleanList.add(true);
EvaluationContext context = SimpleEvaluationContext().forReadOnlyDataBinding().build();
// false is passed in here as a string. SpEL and the conversion service
// correctly recognize that it needs to be a Boolean and convert it
parser.parseExpression("booleanList[0]").setValue(context, simple, "false");
// b is false
Boolean b = simple.booleanList.get(0);
可以使用解析器配置对象(org.springframework.expression.spel.SpelParserConfiguration)配置SpEL表达式解析器。 配置对象控制某些表达式组件的行为。 例如,如果索引到数组或集合,并且指定索引处的元素为null,则可以自动创建该元素。 当使用由一系列属性引用组成的表达式时,这很有用。 如果索引到数组或列表并指定超出数组或列表当前大小末尾的索引,则可以自动增大数组或列表以适应该索引。 以下示例演示通过SpelParserConfiguration类配置自动增长列表:
class Demo {
public List list;
}
//Configuration turns on:
// - auto null reference initialization
// - auto collection growing
SpelParserConfiguration config = new SpelParserConfiguration(true,true);
ExpressionParser parser = new SpelExpressionParser(config);
Expression expression = parser.parseExpression("list[3]");
Demo demo = new Demo();
Object o = expression.getValue(demo);
// demo.list will now be a real collection of 4 entries
// Each entry is a new empty String
Spring Framework 4.1包含一个基本的表达式编译器。表达式通常是被解释执行的,以在计算/执行期间提供很多动态灵活性,但是却导致不能提供最佳性能。对于偶尔的表达式使用,这很好,但是,当其他组件(如Spring Integration)使用时,性能可能非常重要,并且不需要动态。
SpEL编译器旨在满足此需求。在评估期间,编译器生成一个真实的Java类,它体现了表达式行为,并使用它来实现更快的表达式计算/执行。由于缺少表达式类型,编译器编译时使用解释执行的方式去收集信息。例如,编译器不能完全从表达式中知道属性引用的类型,但是,在第一次解释执行时,编译器能够获取起类型信息。当然,如果各种表达元素的类型随时间变化,那么基于此信息的编译可能会导致问题。因此,编译器最适合用于在重复计算/执行类型信息不会改变的表达式。
可以使用org.springframework.expression.spel.SpelCompilerMode枚举类来配置编译器:
从Spring框架4.1版本开始,Spring就开始提供基本的编译框架。然而,该框架并没能支持所有表达式的编译。编译框架最初的目的是编译在关键上下文中经常使用的通用表达式。目前,以下几种表达式不能被编译:
属性和构造器参数的值可以使用表达式来设置,例如:
可以使用在域、方法或狗在其参数前使用@Value注释来指定一个默认的值。例如:
public static class FieldValueTestBean {
@Value("#{ systemProperties['user.region'] }")
private String defaultLocale;
public void setDefaultLocale(String defaultLocale) {
this.defaultLocale = defaultLocale;
}
public String getDefaultLocale() {
return this.defaultLocale;
}
}
public static class PropertyValueTestBean {
private String defaultLocale;
@Value("#{ systemProperties['user.region'] }")
public void setDefaultLocale(String defaultLocale) {
this.defaultLocale = defaultLocale;
}
public String getDefaultLocale() {
return this.defaultLocale;
}
}
public class SimpleMovieLister {
private MovieFinder movieFinder;
private String defaultLocale;
@Autowired
public void configure(MovieFinder movieFinder,
@Value("#{ systemProperties['user.region'] }") String defaultLocale) {
this.movieFinder = movieFinder;
this.defaultLocale = defaultLocale;
}
// ...
}
public class MovieRecommender {
private String defaultLocale;
private CustomerPreferenceDao customerPreferenceDao;
@Autowired
public MovieRecommender(CustomerPreferenceDao customerPreferenceDao,
@Value("#{systemProperties['user.country']}") String defaultLocale) {
this.customerPreferenceDao = customerPreferenceDao;
this.defaultLocale = defaultLocale;
}
// ...
}
文字表达式支持字符串、数值(int, real, hex)、布尔型和空这几种类型。字符串放在单引号中。如果在字符串中有单引号字符,则使用两个单引号字符来表示。
例如:
ExpressionParser parser = new SpelExpressionParser();
// evals to "Hello World"
String helloWorld = (String) parser.parseExpression("'Hello World'").getValue();
double avogadrosNumber = (Double) parser.parseExpression("6.0221415E+23").getValue();
// evals to 2147483647
int maxValue = (Integer) parser.parseExpression("0x7FFFFFFF").getValue();
boolean trueValue = (Boolean) parser.parseExpression("true").getValue();
Object nullValue = parser.parseExpression("null").getValue();
SimpleEvaluationContext并未限制文字类的表达式。
Spring表达式可允许用户通过表达式访问指定对象的属性,SimpleEvaluationContext并未限制通过表达式访问对象的属性。例如:
ExpressionParser parser = new SpelExpressionParser();
GregorianCalendar calendar = new GregorianCalendar();
calendar.set(1856, 7, 9);
Inventor inventor = new Inventor("Alice Miller", calendar.getTime(), "America");
PlaceOfBirth placeOfBirth = new PlaceOfBirth("NewYork", "America");
inventor.setPlaceOfBirth(placeOfBirth);
EvaluationContext simpleEvaluationContext = SimpleEvaluationContext.forReadWriteDataBinding().withRootObject(inventor).build();
int year = (Integer) parser.parseExpression("birthdate.Year + 100").getValue(simpleEvaluationContext);
System.out.println(year);
String city = (String) parser.parseExpression("placeOfBirth.city").getValue(simpleEvaluationContext);
System.out.println(city);
Spring表达式可允许用户通过表达式访问指定数组,SimpleEvaluationContext并未限制通过表达式访问数组。例如:
ExpressionParser parser = new SpelExpressionParser();
Inventor inventor = new Inventor();
String[] inventions = {"telephone","cap","cellphone","desktop"};
inventor.setInventions(inventions);
EvaluationContext simpleEvaluationContext = SimpleEvaluationContext.forReadWriteDataBinding().build();
String invention = parser.parseExpression("inventions[3]").getValue(simpleEvaluationContext, inventor, String.class);
System.out
.println(invention);
ExpressionParser parser = new SpelExpressionParser();
Inventor inventor = new Inventor();
String[] inventions = {"telephone","cap","cellphone","desktop"};
inventor.setInventions(inventions);
EvaluationContext simpleEvaluationContext = SimpleEvaluationContext.forReadWriteDataBinding().build();
String invention = parser.parseExpression("inventions[3]").getValue(simpleEvaluationContext, inventor, String.class);
System.out.println(invention);
Spring表达式可允许用户通过表达式访问指定List,SimpleEvaluationContext并未限制通过表达式访问List。例如:
ExpressionParser parser = new SpelExpressionParser();
EvaluationContext simpleEvaluationContext = SimpleEvaluationContext.forReadWriteDataBinding().build();
Society ieee = new Society();
GregorianCalendar calendar = new GregorianCalendar();
calendar.set(1856, 7, 9);
Inventor inventor = new Inventor("Alice Miller", calendar.getTime(), "America");
ieee.addMember(inventor);
String name = parser.parseExpression("Members[0].Name").getValue(simpleEvaluationContext, ieee, String.class);
System.out.println(name);
Spring表达式可允许用户通过表达式访问Map,SimpleEvaluationContext并未限制通过表达式访问Map。例如:
ExpressionParser parser = new SpelExpressionParser();
EvaluationContext simpleEvaluationContext = SimpleEvaluationContext.forReadWriteDataBinding().build();
Map officers = new HashMap();
GregorianCalendar calendar = new GregorianCalendar();
calendar.set(1856, 7, 9);
Inventor inventor = new Inventor("Alice Miller", calendar.getTime(), "America");
officers.put("president",inventor);
simpleEvaluationContext.setVariable("Officers",officers);
Inventor inventor1 = parser.parseExpression("#Officers['president']").getValue(simpleEvaluationContext, Inventor.class);
System.out.println(inventor1.getName());
在Spring表达式中,可以直接使用{}来表达一个列表,SimpleEvaluationContext并未限制通过表达式访问Inline lists。例如:
ExpressionParser parser = new SpelExpressionParser();
EvaluationContext simpleEvaluationContext = SimpleEvaluationContext.forReadWriteDataBinding().build();
java.util.List numbers = (java.util.List) parser.parseExpression("{1,2,3,4,5}").getValue(simpleEvaluationContext);
System.out.println(numbers.get(3)+"~");
java.util.List listOfLists = (java.util.List) parser.parseExpression("{{'a','b'},{'x','y'}}").getValue(simpleEvaluationContext);
System.out.println(((List)listOfLists.get(1)).get(1));
在Spring表达式中,可以使用{key:value},SimpleEvaluationContext并未限制通过表达式访问Inline Maps。例如:
ExpressionParser parser = new SpelExpressionParser();
EvaluationContext simpleEvaluationContext = SimpleEvaluationContext.forReadWriteDataBinding().build();
Map inventorInfo = (Map) parser.parseExpression("{name:'Nikola',dob:'10-July-1856'}").getValue(simpleEvaluationContext);
System.out.println(inventorInfo.get("name"));
Map mapOfMaps = (Map) parser.parseExpression("{name:{first:'Nikola',last:'Tesla'},dob:{day:10,month:'July',year:1856}}").getValue(simpleEvaluationContext);
System.out.println(((Map)mapOfMaps.get("dob")).get("day"));
Spring表达式支持在表达式中构造数组,SimpleEvaluationContext并未限制通过表达式构造数组。例如:
ExpressionParser parser = new SpelExpressionParser();
EvaluationContext simpleEvaluationContext = SimpleEvaluationContext.forReadWriteDataBinding().build();
int[] numbers1 = (int[]) parser.parseExpression("new int[4]").getValue(simpleEvaluationContext);
numbers1[3] = 2;
for (int num : numbers1) {
System.out.print(num);
System.out.print(" ");
}
System.out.println();
// Array with initializer
int[] numbers2 = (int[]) parser.parseExpression("new int[]{1,2,3}").getValue(simpleEvaluationContext);
for (int num : numbers2) {
System.out.print(num);
System.out.print(" ");
}
System.out.println();
// Multi dimensional array
int[][] numbers3 = (int[][]) parser.parseExpression("new int[4][5]").getValue(simpleEvaluationContext);
numbers3[3][2] = 32;
for (int[] num_x:numbers3) {
for
(int num : num_x) {
System.out.print(num);
System.out.print(" ");
}
}
System.out.println();
Spring表达式支持在表达式中调用方法。
注意:SimpleEvaluationContext默认情况下是不允许调用方法的。但是提供了withInstanceMethods()和withMethodResolvers()方法来提供方法调用,但是仍然禁止了静态方法调用。
例如:
ExpressionParser parser = new SpelExpressionParser();
EvaluationContext simpleEvaluationContext = SimpleEvaluationContext.forReadWriteDataBinding().withInstanceMethods().build();
Society ieee = new Society();
GregorianCalendar calendar = new GregorianCalendar();
calendar.set(1856, 7, 9);
Inventor inventor = new Inventor("Alice Miller", calendar.getTime(), "America");
ieee.addMember(inventor);
boolean isMember = parser.parseExpression("isMember('Alice Miller')").getValue(simpleEvaluationContext,ieee,Boolean.class);
System.out.println(isMember);
String subStr = (String) parser.parseExpression("'abc'.substring(1,3)").getValue(simpleEvaluationContext);
System.out.println(subStr);
//Exception in thread "main" org.springframework.expression.spel.SpelEvaluationException: EL1004E: Method call: Method staticMethod() cannot be found on com.pow.study.spel.inventor.Society type
String invokeStr = (String) parser.parseExpression("staticMethod()").getValue(simpleEvaluationContext, ieee);
System.out.println(invokeStr);
Spring表达式支持关系运算符,SimpleEvaluationContext并未限制表达式中的关系运算符。例如:
ExpressionParser parser = new SpelExpressionParser();
EvaluationContext simpleEvaluationContext = SimpleEvaluationContext.forReadWriteDataBinding().build();
// evaluates to true
boolean boolValue1 = parser.parseExpression("2 == 2").getValue(simpleEvaluationContext, Boolean.class);
System.out.println(boolValue1);
// evaluates to false
boolean boolValue2 = parser.parseExpression("2 < -5.0").getValue(simpleEvaluationContext, Boolean.class);
System.out.println(boolValue2);
// evaluates to true
boolean boolValue3 = parser.parseExpression("'black' < 'block'").getValue(simpleEvaluationContext, Boolean.class);
System.out.println(boolValue3);
Spring表达式支持逻辑运算符(and, or, not),SimpleEvaluationContext并未限制表达式中的逻辑运算符。例如:
ExpressionParser parser = new SpelExpressionParser();
EvaluationContext simpleEvaluationContext = SimpleEvaluationContext.forReadWriteDataBinding().build();
// evaluates to false
boolean boolValue1 = parser.parseExpression("true and false").getValue(simpleEvaluationContext, Boolean.class);
System.out.println(boolValue1);
// evaluates to false
boolean boolValue2 = parser.parseExpression("!true").getValue(simpleEvaluationContext, Boolean.class);
System.out.println(boolValue2);
// evaluates to true
boolean boolValue3 = parser.parseExpression("true or false").getValue(simpleEvaluationContext, Boolean.class);
System.out.println(boolValue3);
Spring表达式支持数学运算符,SimpleEvaluationContext并未限制表达式中的数学运算符。例如:
ExpressionParser parser = new SpelExpressionParser();
EvaluationContext simpleEvaluationContext = SimpleEvaluationContext.forReadWriteDataBinding().build();
// Addition
int add = parser.parseExpression("2 + 2").getValue(simpleEvaluationContext, Integer.class);
System.out.println(add);
// Subtraction
int sub = parser.parseExpression("7 - 2").getValue(simpleEvaluationContext, Integer.class);
System.out.println(sub);
// Multiplication
int mul = parser.parseExpression("6 * 3").getValue(simpleEvaluationContext, Integer.class);
System.out.println(mul);
// Division
int div = parser.parseExpression("6 / 3").getValue(simpleEvaluationContext, Integer.class);
System.out.println(div);
// Modulus
int mod = parser.parseExpression("6 % 3").getValue(simpleEvaluationContext, Integer.class);
System.out.println(mod);
// Operator precedence
int result = parser.parseExpression("(3 + 5) / 2").getValue(simpleEvaluationContext, Integer.class);
System.out.println(result);
Spring表达式支持在表达式中进行赋值操作,SimpleEvaluationContext并未限制表达式中的赋值操作。例如:
ExpressionParser parser = new SpelExpressionParser();
EvaluationContext simpleEvaluationContext = SimpleEvaluationContext.forReadWriteDataBinding().build();
int num = 8;
simpleEvaluationContext.setVariable("num", num);
// num = 9
num = (Integer) parser.parseExpression("#num = 9").getValue(simpleEvaluationContext);
System.out.println(num);
T操作符用来指定一个java.lang.Class的实例(types)。静态方法也可以使用这个操作符来调用,例如:T(java.lang.Math).random()。
StandardEvaluationContext可以使用一个TypeLocator来找到指定的type,但是SimpleEvaluationContext不支持在表达式中使用T操作符来指定一个类。例如:
ExpressionParser parser = new SpelExpressionParser();
EvaluationContext simpleEvaluationContext = SimpleEvaluationContext.forReadWriteDataBinding().build();
EvaluationContext standardEvaluationContext = new StandardEvaluationContext();
//result : java.lang.Math
Class mathClass = parser.parseExpression("T(java.lang.Math)").getValue(standardEvaluationContext, Class.class);
System.out.println(mathClass.getName());
//Exception in thread "main" org.springframework.expression.spel.SpelEvaluationException: EL1005E: Type cannot be found 'java.util.Date'
Class dateClass = parser.parseExpression("T(java.util.Date)").getValue(simpleEvaluationContext, Class.class);
System.out.println(dateClass.getName());
Spring表达式支持在表达式中使用构造器来创建对象(new)。StandardEvaluationContext可以使用ConstructorResolvers来处理new操作,但是SimpleEvaluationContext不支持。例如:
ExpressionParser parser = new SpelExpressionParser();
EvaluationContext simpleEvaluationContext = SimpleEvaluationContext.forReadWriteDataBinding().build();
EvaluationContext standardEvaluationContext = new StandardEvaluationContext();
//result : Albert Einstein
Inventor inventor1 = parser.parseExpression("new com.pow.study.spel.inventor.Inventor('Albert Einstein', 'Germany')").getValue(standardEvaluationContext, Inventor.class);
System.out.println(inventor1.getName());
//Exception in thread "main" org.springframework.expression.spel.SpelEvaluationException: EL1002E: Constructor call: No suitable constructor found on type com.pow.study.spel.inventor.Inventor for arguments (java.lang.String,java.lang.String)
Inventor inventor2 = parser.parseExpression("new com.pow.study.spel.inventor.Inventor('Alice Miller', 'America')").getValue(simpleEvaluationContext, Inventor.class);
System.out.println(inventor2.getName());
Spring表达式支持在表达式中使用变量。SimpleEvaluationContext也同样支持这一功能。例如:
ExpressionParser parser = new SpelExpressionParser();
EvaluationContext simpleEvaluationContext = SimpleEvaluationContext.forReadWriteDataBinding().build();
Inventor inventor = new Inventor("Alice Miller", "America");
simpleEvaluationContext.setVariable("newName", "Nikola Tesla");
parser.parseExpression("Name = #newName").getValue(simpleEvaluationContext, inventor);
System.out.println(inventor.getName());
注意:
ExpressionParser parser = new SpelExpressionParser();
EvaluationContext simpleEvaluationContext = SimpleEvaluationContext.forReadWriteDataBinding().build();
Inventor inventor = new Inventor("Alice Miller", "America”);
//com.pow.study.spel.inventor.Inventor
Object object = parser.parseExpression("#root").getValue(simpleEvaluationContext,inventor);
System.out.println(object.getClass().getName());
List primes = new ArrayList();
primes.addAll(Arrays.asList(2,3,5,7,11,13,17,19,23,29,31,37,41));
simpleEvaluationContext.setVariable("primes", primes);
//11, 13, 17, 19, 23, 29, 31, 37, 41]
List primesGreaterThanTen = (List) parser.parseExpression("#primes.?[#this>10]").getValue(simpleEvaluationContext);
System.out.println(primesGreaterThanTen);
Spring表达式支持用户调用已注册的静态函数。其中,StandardEvaluationContext支持setVariable()方法和registerFunction()方法注册静态函数,但是SimpleEvaluationContext()只支持setVariable()方法。例如:
ExpressionParser parser = new SpelExpressionParser();
EvaluationContext simpleEvaluationContext = SimpleEvaluationContext.forReadWriteDataBinding().withInstanceMethods().build();
StandardEvaluationContext standardEvaluationContext = new StandardEvaluationContext();
try {
Method random = java.lang.Math.class.getDeclaredMethod("random");
Method getRuntime = java.lang.Runtime.class.getDeclaredMethod("getRuntime");
standardEvaluationContext.setVariable("random", random);
standardEvaluationContext.registerFunction("getRuntime", getRuntime);
simpleEvaluationContext.setVariable("random",random);
simpleEvaluationContext.setVariable("getRuntime", getRuntime);
//get a random
Object o = parser.parseExpression("#random()").getValue(standardEvaluationContext);
System.out.println(o);
//open a calculator
Object o1 = parser.parseExpression("#getRuntime().exec('open /Applications/Calculator.app')").getValue(standardEvaluationContext);
System.out.println(o1);
//get a random
Object o2 = parser.parseExpression("#random()").getValue(simpleEvaluationContext);
System.out.println(o2);
//open a calculator
Object o3 = parser.parseExpression("#getRuntime().exec('open /Applications/Calculator.app')").getValue(simpleEvaluationContext);
System.out.println(o3);
} catch (NoSuchMethodException e) {
System.out.println(e.getMessage());
}
Spring 表达式支持BeanReference。StandardEvaluationContext允许用户使用setBeanResolver方法注册bean并进行调用,但SimpleEvaluationContext不支持这种类型的表达式。
package com.pow.study.spel;
import org.springframework.expression.AccessException;
import org.springframework.expression.BeanResolver;
import org.springframework.expression.EvaluationContext;
import org.springframework.expression.ExpressionParser;
import org.springframework.expression.spel.standard.SpelExpressionParser;
import org.springframework.expression.spel.support.StandardEvaluationContext;
/**
* @author pow
* @date 2018/10/10 上午10:39
*/
public class BeanReference {
public void test() {
ExpressionParser parser = new SpelExpressionParser();
StandardEvaluationContext context = new StandardEvaluationContext();
context.setBeanResolver(new MyBeanResolver());
Object bean = parser.parseExpression("&foo").getValue(context);
System.out.println(bean);
}
public static void main(String[] args) {
BeanReference demo = new BeanReference();
demo.test();
}
/**
* @author pow
* @date 2018/10/9 下午9:09
*/
public static class MyBeanResolver implements BeanResolver {
@Override
public Object resolve(EvaluationContext context, String beanName) throws AccessException {
if (beanName.equals("foo") || beanName.equals("bar")) {
return "MyBeanResolver";
}
if (beanName.equals("&foo")) {
return "MyBeanResolver-&foo";
}
throw new AccessException("not heard of " + beanName);
}
}
}
Spring表达式支持IF-THEN-ELSE的三元运算符。SimpleEvaluationContext也支持该类表达式,例如:
ExpressionParser parser = new SpelExpressionParser();
EvaluationContext simpleEvaluationContext = SimpleEvaluationContext.forReadWriteDataBinding().build();
//falseExp
String string = parser.parseExpression("false ? 'trueExp' : 'falseExp'").getValue(simpleEvaluationContext, String.class);
System.out.println(string);
Spring表达式支持name?:”Unknown”(等价于:name == null ? name : “Unknown")类型的逻辑运算。SimpleEvaluationContext也支持该类表达式,例如:
ExpressionParser parser = new SpelExpressionParser();
EvaluationContext simpleEvaluationContext = SimpleEvaluationContext.forReadWriteDataBinding().build();
String name = "Elvis Presley";
simpleEvaluationContext.setVariable("name", name);
//Elvis Presley
String string = parser.parseExpression("#name?:'Unknown'").getValue(simpleEvaluationContext, String.class);
System.out.println(string);
Safe Navigation Operator用来避免空指针异常。如果在调用某对象的某一属性时,如果对象为空,则返回空,而不是抛出异常。SimpleEvaluationContext也支持这一类表达式。例如:
ExpressionParser parser = new SpelExpressionParser();
EvaluationContext context = SimpleEvaluationContext.forReadOnlyDataBinding().build();
Inventor tesla = new Inventor("Nikola Tesla", "Serbian");
tesla.setPlaceOfBirth(new PlaceOfBirth("Smiljan"));
String city = parser.parseExpression("PlaceOfBirth?.City").getValue(context, tesla, String.class);
System.out.println(city); // Smiljan
tesla.setPlaceOfBirth(null);
city = parser.parseExpression("PlaceOfBirth?.City").getValue(context, tesla, String.class);
System.out.println(city); // null - does not throw NullPointerException!!!
筛选是表达式语言中的一个强大功能,Spring表达式支持此功能,且在SimpleEvaluationContext中也支持。例如:
ExpressionParser parser = new SpelExpressionParser();
EvaluationContext simpleEvaluationContext = SimpleEvaluationContext.forReadWriteDataBinding().build();
Society ieee = new Society();
GregorianCalendar calendar = new GregorianCalendar();
calendar.set(1856, 7, 9);
Inventor inventor = new Inventor("Alice Miller", calendar.getTime(), "America");
ieee.addMember(inventor);
List list = (List) parser.parseExpression("Members.?[Name == 'Alice Miller']").getValue(simpleEvaluationContext, ieee);
System.out.println(list.get(0).getName());//Alice Miller
Spring表达式也支持映射,(与context类型无关)。例如:
ExpressionParser parser = new SpelExpressionParser();
EvaluationContext simpleEvaluationContext = SimpleEvaluationContext.forReadWriteDataBinding().build();
Society ieee = new Society();
GregorianCalendar calendar = new GregorianCalendar();
calendar.set(1856, 7, 9);
Inventor inventor = new Inventor("Alice Miller", calendar.getTime(), "America");
Inventor inventor1 = new Inventor("Bob White", calendar.getTime(), "America");
ieee.addMember(inventor);
ieee.addMember(inventor1);
List list = (List) parser.parseExpression("Members.![Name]").getValue(simpleEvaluationContext, ieee);
System.out.println(list);//[Alice Miller, Bob White]
表达式模板允许文字文本与一个或多个解析块的混合。 你可以每个解析块分隔前缀和后缀的字符, 当然,常见的选择是使用#{}作为分隔符。SimpleEvaluationContext也支持,例如:
ExpressionParser parser = new SpelExpressionParser();
EvaluationContext simpleEvaluationContext = SimpleEvaluationContext.forReadWriteDataBinding().build();
String str = parser.parseExpression(
"The result of '1 == 2' is #{1 == 2}",
new TemplateParserContext()).getValue(String.class);
System.out.println(str);//The result of '1 == 2' is false
本文使用的例子:https://github.com/hjkyoyo/spring-expression-study/
参考文章:
https://docs.spring.io/spring/docs/current/spring-framework-reference/core.html#expressions-evaluation