Spring Expression Language(简称SpEL)是一种强大的表达式语言,支持在运行时查询和操作对象图。语言语法类似于 Unified EL,但提供了额外的功能,最值得注意的是方法调用和基本的字符串模板功能。
虽然 SpEL 是 Spring 产品组合中表达式评估的基础,但它不直接与 Spring 绑定,可以独立使用。为了自成一体,本章中的许多示例都使用 SpEL,就好像它是一种独立的表达语言一样。这需要创建一些引导基础设施类,例如解析器。大多数 Spring 用户不需要处理这个基础设施,而是只编写表达式字符串进行评估。这种典型用途的一个示例是将 SpEL 集成到创建 XML 或基于注释的 bean 定义中

Example

  1. public class TestCase {
  2. public static void main(String[] args) {
  3. //初始化对象
  4. Account account = new Account();
  5. account.setFootballCount(10);
  6. account.setName("Jeff");
  7. account.setFriend(new Friend("Jack"));
  8. testObjAttr(account);
  9. testTemplate(account);
  10. testUsefulFun(account);
  11. }
  12. /**
  13. * 使用4:测试Spring容器bean动态调用方法,本方法内无法运行
  14. */
  15. private static void testSpringBean() {
  16. String template = "#{@testController.getSql()}";// 此处使用@beanName的方式调用
  17. ExpressionParser parser = new SpelExpressionParser();
  18. ApplicationContext applicationContext = null; // 注入方式获取applicationContext
  19. //通过evaluationContext.setVariable可以在上下文中设定变量
  20. StandardEvaluationContext context = new StandardEvaluationContext();
  21. context.setBeanResolver(new BeanFactoryResolver(applicationContext));
  22. //解析表达式,如果表达式是一个模板表达式,需要为解析传入模板解析器上下文。
  23. Expression expression = parser.parseExpression(template, new TemplateParserContext());
  24. System.out.println(expression.getValue(context, String.class));
  25. }
  26. /**
  27. * 使用3:测试内置函数方法
  28. * @param account
  29. */
  30. private static void testUsefulFun(Account account) {
  31. // 字符串表达式结果,直接通过spel解析获取
  32. ExpressionParser parser = new SpelExpressionParser();
  33. Boolean bool = parser.parseExpression("2 == 2").getValue(Boolean.class);
  34. System.out.println(bool);
  35. parser = new SpelExpressionParser();
  36. bool = parser.parseExpression("'5.00' matches '^-?\\d+(\\.\\d{2})?$'").getValue(Boolean.class);
  37. System.out.println(bool);
  38. }
  39. /**
  40. * 使用2:模版属性
  41. */
  42. private static void testTemplate(Account account) {
  43. //设置文字模板,其中#{}表示表达式的起止,#user是表达式字符串,表示引用一个变量。
  44. String template = "#{#user}, good morning!, and you #{#account.name} ? #{#account.alwaysTrue ? 'true' :' false'} " +
  45. " #{#account.setName(#myname)} #{#account.getName()}";
  46. ExpressionParser parser = new SpelExpressionParser();
  47. //通过evaluationContext.setVariable可以在上下文中设定变量
  48. EvaluationContext context = new StandardEvaluationContext();
  49. context.setVariable("user", "zhan");
  50. context.setVariable("account", account);
  51. context.setVariable("myname", "qian2222");//此处是修改account的name用法
  52. //解析表达式,如果表达式是一个模板表达式,需要为解析传入模板解析器上下文。
  53. Expression expression = parser.parseExpression(template, new TemplateParserContext());
  54. //使用Expression.getValue()获取表达式的值,这里传入了Evalution上下文,第二个参数是类型参数,表示返回值的类型。
  55. System.out.println(expression.getValue(context, String.class));
  56. }
  57. /**
  58. * 使用1:测试对象属性
  59. */
  60. private static void testObjAttr(Account account) {
  61. // 解析器
  62. ExpressionParser parser = new SpelExpressionParser();
  63. // 解析上下文
  64. EvaluationContext context = new StandardEvaluationContext(account);
  65. Expression expression = parser.parseExpression("name");
  66. String value = expression.getValue(context, String.class);
  67. System.out.println(value);
  68. expression = parser.parseExpression("friend.name");
  69. String value2 = expression.getValue(context, String.class);
  70. System.out.println(value2);
  71. }
  72. @Data
  73. public static class Account {
  74. private String name;
  75. private int footballCount;
  76. private Friend friend;
  77. }
  78. @Builder
  79. @Data
  80. public static class Friend {
  81. private String name;
  82. }
  83. }

参考

【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