1 基本java表达式计算
1.1 核心类
ExpressionParser parser = new SpelExpressionParser();
1.2 使用方式
字符串里面的表达式,只要符合java代码执行,则可以通过spring el进行计算,并获取结果。
String expression = "'Hello World'";
ExpressionParser parser = new SpelExpressionParser();
Expression exp = parser.parseExpression(expression);
String message = (String) exp.getValue();
message = exp.getValue(String.class);
String expression = "'Hello World'.concat('!')";
ExpressionParser parser = new SpelExpressionParser();
Expression exp = parser.parseExpression(expression);
String message = exp.getValue(String.class);
获取结果,进行类型转换,可以指定结果类型,也可以强制类型转换,如果类型和实际不一样,会抛出异常
EvaluationException
。
具体参考 Expression#getValue()
扩展:
GregorianCalendar c = new GregorianCalendar();
c.set(1856, 7, 9);
// Inventor 是一个对象
Inventor tesla = new Inventor("Nikola Tesla", c.getTime(), "Serbian");
ExpressionParser parser = new SpelExpressionParser();
// 解析 name ,name是 Inventor 一个属性
Expression exp = parser.parseExpression("name");
// 在 expression 中传入 Inventor 对象,则可以调用 name 属性
String name = (String) exp.getValue(tesla);
// name == "Nikola Tesla"
exp = parser.parseExpression("name == 'Nikola Tesla'");
boolean result = exp.getValue(tesla, Boolean.class);
2 EvaluationContext
EvaluationContext
是一个接口,有2个实现,功能各有不同:
-
SimpleEvaluationContext
只有部分spring el 特性。 -
StandardEvaluationContext
更全的功能。
2.1 类型转换
class Simple {
public List<Boolean> booleanList = new ArrayList<Boolean>();
}
Simple simple = new Simple();
simple.booleanList.add(true);
EvaluationContext context = SimpleEvaluationContext.forReadOnlyDataBinding().build();
// 这里设置 `booleanList[0]` 为 `false`, 传入的是一个 `false` 字符串,但是能自动转为 `boolean` 类型,并设置到 `booleanList[0]` 中。
parser.parseExpression("booleanList[0]").setValue(context, simple, "false");
// b is false
Boolean b = simple.booleanList.get(0);
3 解析配置
核心类 SpelParserConfiguration
class Demo {
public List<String> list;
}
// 第一个参数,开启null属性,自动赋值,第二个参数,设置集合动态扩容。
SpelParserConfiguration config = new SpelParserConfiguration(true,true);
ExpressionParser parser = new SpelExpressionParser(config);
Expression expression = parser.parseExpression("list[3]");
Demo demo = new Demo();
// 表达式中是想获取 list[3] 的值,由于配置了默认初始化以及扩容,这里就会使 list 自动扩容 length 为 4,每个值为空字符串。
Object o = expression.getValue(demo);
通过配置 SpelParserConfiguration
配置2个参数。
空值初始化,以及集合自动扩展,值为指定类型的默认值。
4 编译 compiler vs 解释 interpreter
spring 框架最初提供的就是解释模式,但是性能不佳,后面提供编译模式选择,会在计算的时候生成class,提高计算性能。默认是不开启编译模式的。
4.1 编译模式有3中选项:
org.springframework.expression.spel.SpelCompilerMode
类中 - OFF
(default): 默认关闭. -
IMMEDIATE:尽可能快地进行表达式编译,如果失败,抛出异常 - MIXED:
混合,编译和解释2种状态转换,首选编译,如果get wrong , 则切换至解释。
4.2 示例
SpelParserConfiguration config = new SpelParserConfiguration(SpelCompilerMode.IMMEDIATE,
this.getClass().getClassLoader());
SpelExpressionParser parser = new SpelExpressionParser(config);
Expression expr = parser.parseExpression("payload");
MyMessage message = new MyMessage();
Object payload = expr.getValue(message);
4.3 第二种设置 compiler 方式
4.4 complier 限制
-
表达式中涉及任务
-
Expressions relying on the conversion service
-
Expressions using custom resolvers or accessors
-
Expressions using selection or projection
5 在定义中使用表达式
xml、以及注解方式,xml就不用了。注解使用 #{ <expression string> }
.
-
在属性上使用
-
在set方法上使用
-
在方法参数前使用
@Value("#{ systemProperties['user.region'] }")
private String defaultLocale;
@Value("#{ systemProperties['user.region'] }")
public void setDefaultLocale(String defaultLocale) {
this.defaultLocale = defaultLocale;
}
@Autowired
public void configure(MovieFinder movieFinder,
@Value("#{ systemProperties['user.region'] }") String defaultLocale) {
this.movieFinder = movieFinder;
this.defaultLocale = defaultLocale;
}
6 常见的表达式使用
6.1 字面量表达式
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();
6.2 属性、数组、集合表达式
// evals to 1856
int year = (Integer) parser.parseExpression("birthdate.year + 1900").getValue(context);
String city = (String) parser.parseExpression("placeOfBirth.city").getValue(context);
ExpressionParser parser = new SpelExpressionParser();
EvaluationContext context = SimpleEvaluationContext.forReadOnlyDataBinding().build();
// Inventions Array
// evaluates to "Induction motor"
String invention = parser.parseExpression("inventions[3]").getValue(
context, tesla, String.class);
// Members List
// evaluates to "Nikola Tesla"
String name = parser.parseExpression("members[0].name").getValue(
context, ieee, String.class);
// List and Array navigation
// evaluates to "Wireless communication"
String invention = parser.parseExpression("members[0].inventions[6]").getValue(
context, ieee, String.class);
6.3 其他总结下,具体看官网
符号 | 含义 |
---|---|
lt (<) |
|
gt (>) |
|
le (⇐) |
|
ge (>=) |
|
eq (==) |
|
ne (!=) |
|
div (/) |
|
mod (%) |
|
not (!) |
|
and (&&) |
|
or (||) |
|
T(java.util.Date) |
函数,java.lang 下函数只需要类名,其他的需要包名加类名 |
#variableName |
获取变量 |
#this |
当前 |
@something |
bean对象 |
alse ? ‘trueExp’ : ‘falseExp’ |
If-Then-Else 三目运算符 |
name?:'`Unknown’ |
空值赋值默认值 |
placeOfBirth?.city |
防止空指针异常 |
.?[selectionExpression] |
集合筛选 |
.![projectionExpression] |
集合推断 |
#\{ } |
表达式模板 |
具体用法:https://docs.spring.io/spring-framework/docs/current/reference/html/core.html#expressions-properties-arrays