Spring Expression Language(简称SpEL)是一种强大的表达式语言,支持在运行时查询和操作对象图。语言语法类似于 Unified EL,但提供了额外的功能,最值得注意的是方法调用和基本的字符串模板功能。
虽然 SpEL 是 Spring 产品组合中表达式评估的基础,但它不直接与 Spring 绑定,可以独立使用。为了自成一体,本章中的许多示例都使用 SpEL,就好像它是一种独立的表达语言一样。这需要创建一些引导基础设施类,例如解析器。大多数 Spring 用户不需要处理这个基础设施,而是只编写表达式字符串进行评估。这种典型用途的一个示例是将 SpEL 集成到创建 XML 或基于注释的 bean 定义中
Example
public class TestCase {
public static void main(String[] args) {
//初始化对象
Account account = new Account();
account.setFootballCount(10);
account.setName("Jeff");
account.setFriend(new Friend("Jack"));
testObjAttr(account);
testTemplate(account);
testUsefulFun(account);
}
/**
* 使用4:测试Spring容器bean动态调用方法,本方法内无法运行
*/
private static void testSpringBean() {
String template = "#{@testController.getSql()}";// 此处使用@beanName的方式调用
ExpressionParser parser = new SpelExpressionParser();
ApplicationContext applicationContext = null; // 注入方式获取applicationContext
//通过evaluationContext.setVariable可以在上下文中设定变量
StandardEvaluationContext context = new StandardEvaluationContext();
context.setBeanResolver(new BeanFactoryResolver(applicationContext));
//解析表达式,如果表达式是一个模板表达式,需要为解析传入模板解析器上下文。
Expression expression = parser.parseExpression(template, new TemplateParserContext());
System.out.println(expression.getValue(context, String.class));
}
/**
* 使用3:测试内置函数方法
* @param account
*/
private static void testUsefulFun(Account account) {
// 字符串表达式结果,直接通过spel解析获取
ExpressionParser parser = new SpelExpressionParser();
Boolean bool = parser.parseExpression("2 == 2").getValue(Boolean.class);
System.out.println(bool);
parser = new SpelExpressionParser();
bool = parser.parseExpression("'5.00' matches '^-?\\d+(\\.\\d{2})?$'").getValue(Boolean.class);
System.out.println(bool);
}
/**
* 使用2:模版属性
*/
private static void testTemplate(Account account) {
//设置文字模板,其中#{}表示表达式的起止,#user是表达式字符串,表示引用一个变量。
String template = "#{#user}, good morning!, and you #{#account.name} ? #{#account.alwaysTrue ? 'true' :' false'} " +
" #{#account.setName(#myname)} #{#account.getName()}";
ExpressionParser parser = new SpelExpressionParser();
//通过evaluationContext.setVariable可以在上下文中设定变量
EvaluationContext context = new StandardEvaluationContext();
context.setVariable("user", "zhan");
context.setVariable("account", account);
context.setVariable("myname", "qian2222");//此处是修改account的name用法
//解析表达式,如果表达式是一个模板表达式,需要为解析传入模板解析器上下文。
Expression expression = parser.parseExpression(template, new TemplateParserContext());
//使用Expression.getValue()获取表达式的值,这里传入了Evalution上下文,第二个参数是类型参数,表示返回值的类型。
System.out.println(expression.getValue(context, String.class));
}
/**
* 使用1:测试对象属性
*/
private static void testObjAttr(Account account) {
// 解析器
ExpressionParser parser = new SpelExpressionParser();
// 解析上下文
EvaluationContext context = new StandardEvaluationContext(account);
Expression expression = parser.parseExpression("name");
String value = expression.getValue(context, String.class);
System.out.println(value);
expression = parser.parseExpression("friend.name");
String value2 = expression.getValue(context, String.class);
System.out.println(value2);
}
@Data
public static class Account {
private String name;
private int footballCount;
private Friend friend;
}
@Builder
@Data
public static class Friend {
private String name;
}
}
参考
【1】:https://docs.spring.io/spring-framework/docs/3.2.x/spring-framework-reference/html/expressions.html
【2】:https://blog.csdn.net/jaune161/article/details/51476007
【3】:https://www.jianshu.com/p/14e54863faae 动态调用bean方法
【4】:https://zhuanlan.zhihu.com/p/174786047