SpEL - Spring Expression Language - 快速入门

x33g5p2x  于2022-05-06 转载在 Spring  
字(12.1k)|赞(0)|评价(0)|浏览(658)

1. SpEL

注意: 强烈建议过一遍文档(不懂英文,直接Edge翻译、谷歌翻译网页)哦,这部分的内容并不多,跟着Demo敲就完事了

官方文档: https://docs.spring.io/spring-framework/docs/current/reference/html/core.html#expressions

1.1 功能

注意: 测试Demo用到的第三方工具包是Hutool哦

1.1.1 .属性名、方法名(必须是public) - (支持嵌套即多点点)
1.1.1.1 无判空操作

注意: .属性名 == 如果对象没有此字段定义,则会调用get属性名() 方法进行获取值

  1. package top.linruchang.myblog;
  2. import cn.hutool.core.lang.Console;
  3. import org.junit.jupiter.api.Test;
  4. import org.springframework.expression.Expression;
  5. import org.springframework.expression.ExpressionParser;
  6. import org.springframework.expression.spel.standard.SpelExpressionParser;
  7. import java.util.Arrays;
  8. /**
  9. * 作用:
  10. *
  11. * @author LinRuChang
  12. * @version 1.0
  13. * @date 2022/05/06
  14. * @since 1.8
  15. **/
  16. public class SpELTest {
  17. @Test
  18. public void test1() {
  19. ExpressionParser parser = new SpelExpressionParser();
  20. Expression exp = parser.parseExpression("'Hello World'.bytes");
  21. byte[] bytes = (byte[]) exp.getValue();
  22. Console.log(bytes);
  23. System.out.println(Arrays.toString(bytes));
  24. }
  25. @Test
  26. public void test2() {
  27. ExpressionParser parser = new SpelExpressionParser();
  28. Expression exp = parser.parseExpression("'Hello World'.hash");
  29. Integer hashNum = exp.getValue(Integer.class);
  30. Console.log(hashNum);
  31. System.out.println(hashNum);
  32. }
  33. @Test
  34. public void test3() {
  35. ExpressionParser parser = new SpelExpressionParser();
  36. Expression exp = parser.parseExpression("5.MIN_VALUE");
  37. Integer MIN_VALUE = exp.getValue(Integer.class);
  38. Console.log(MIN_VALUE);
  39. System.out.println(MIN_VALUE);
  40. }
  41. @Test
  42. public void test4() {
  43. ExpressionParser parser = new SpelExpressionParser();
  44. Expression exp = parser.parseExpression("5L.MIN_VALUE");
  45. Long MIN_VALUE = exp.getValue(Long.class);
  46. Console.log(MIN_VALUE);
  47. System.out.println(MIN_VALUE);
  48. }
  49. @Test
  50. public void test5() {
  51. ExpressionParser parser = new SpelExpressionParser();
  52. Expression exp = parser.parseExpression("'5L'.getBytes");
  53. byte[] bytes = exp.getValue(byte[].class);
  54. Console.log(bytes);
  55. System.out.println(bytes);
  56. }
  57. @Test
  58. public void test6() {
  59. ExpressionParser parser = new SpelExpressionParser();
  60. Expression exp = parser.parseExpression("'5L'.getBytes.length");
  61. Integer byteLength = exp.getValue(Integer.class);
  62. Console.log(byteLength);
  63. System.out.println(byteLength);
  64. }
  65. }

1.1.1.2 有判空操作 = 格式=》属性名?
  1. public class DBTest {
  2. public class DBTest {
  3. @Test
  4. public void test16() {
  5. SysUser sysUser = new SysUser();
  6. sysUser.setEmail("邮箱地址");
  7. SpelExpressionParser spelExpressionParser = new SpelExpressionParser();
  8. Expression expression = spelExpressionParser.parseExpression("email?.length");
  9. Object value = expression.getValue(sysUser);
  10. Console.log(value);
  11. //问好等价于下面那句话
  12. expression = spelExpressionParser.parseExpression("nickName?.length");
  13. value = expression.getValue(sysUser);
  14. Console.log(value);
  15. expression = spelExpressionParser.parseExpression("loginName != null ? loginName.length : null");
  16. value = expression.getValue(sysUser);
  17. Console.log(value);
  18. expression = spelExpressionParser.parseExpression("loginName.length");
  19. value = expression.getValue(sysUser);
  20. Console.log(value);
  21. }
  22. }

1.1.2 直接解析调用Java代码 - 【不能直接正常调用静态方法,需要用实例对象.静态方法这样才能调成功】
  1. /**
  2. * 作用:
  3. *
  4. * @author LinRuChang
  5. * @version 1.0
  6. * @date 2022/05/06
  7. * @since 1.8
  8. **/
  9. public class SpELTest {
  10. /**
  11. * 正常使用的静态方法调用不了
  12. */
  13. @Test
  14. public void test7() {
  15. SpelExpressionParser spelExpressionParser = new SpelExpressionParser();
  16. Expression expression = spelExpressionParser.parseExpression("String.valueOf(5)");
  17. String value = expression.getValue(String.class);
  18. Console.log(value);
  19. }
  20. /**
  21. * 间接的调用静态方法
  22. */
  23. @Test
  24. public void test9() {
  25. SpelExpressionParser spelExpressionParser = new SpelExpressionParser();
  26. //静态方法
  27. Expression expression = spelExpressionParser.parseExpression("new Long('5').hashCode(5l)");
  28. Integer value = expression.getValue(Integer.class);
  29. Console.log(value);
  30. //成员方法
  31. expression = spelExpressionParser.parseExpression("new Long('5').floatValue()");
  32. Float value2 = expression.getValue(Float.class);
  33. Console.log(value2);
  34. }
  35. }

1.1.3 解析自定义对象的值
  1. public class SpELTest {
  2. /**
  3. * 静态方法调用不了
  4. */
  5. @Test
  6. public void test10() {
  7. //SysUser sysUser = new SysUser();
  8. //sysUser.setEmail("邮箱地址");
  9. Map sysUser = new HashMap();
  10. sysUser.put("email", "邮箱地址");
  11. SpelExpressionParser spelExpressionParser = new SpelExpressionParser();
  12. //解析某对象的email属性 - Bean对象
  13. //Expression expression = spelExpressionParser.parseExpression("email != null ? email.length() : 0");
  14. //Map == 键值对
  15. //Expression expression = spelExpressionParser.parseExpression("get('email') != null ? get('email').length() : 0");
  16. Expression expression = spelExpressionParser.parseExpression("['email'] != null ? ['email'].length() : 0");
  17. Integer value = expression.getValue(sysUser, Integer.class);
  18. Console.log(value);
  19. }
  20. }

1.1.4 设置对象的值
方式1 - 表达式为属性名
  1. public class SpELTest {
  2. /**
  3. * 静态方法调用不了
  4. */
  5. @Test
  6. public void test11() {
  7. SysUser sysUser = new SysUser();
  8. sysUser.setEmail("邮箱地址");
  9. SpelExpressionParser spelExpressionParser = new SpelExpressionParser();
  10. Expression expression = spelExpressionParser.parseExpression("nickName");
  11. expression.setValue(sysUser,"大家好");
  12. Console.log(sysUser);
  13. }
  14. /**
  15. * 静态方法调用不了
  16. */
  17. @Test
  18. public void test12() {
  19. SysUser sysUser = new SysUser();
  20. sysUser.setEmail("邮箱地址");
  21. SpelExpressionParser spelExpressionParser = new SpelExpressionParser();
  22. //设置el表达式执行标准,【仅能读取属性不能修改属性】
  23. EvaluationContext evaluationContext = SimpleEvaluationContext.forReadOnlyDataBinding().build();
  24. Expression expression = spelExpressionParser.parseExpression("nickName");
  25. expression.setValue(evaluationContext,sysUser,"大家好");
  26. Console.log(sysUser);
  27. }
  28. }

方式2 - 表达式为赋值操作 - 写死
  1. public class DBTest {
  2. /**
  3. * 静态赋值
  4. */
  5. @Test
  6. public void test12_2() {
  7. SysUser sysUser = new SysUser();
  8. sysUser.setEmail("邮箱地址");
  9. SpelExpressionParser spelExpressionParser = new SpelExpressionParser();
  10. Expression expression = spelExpressionParser.parseExpression("nickName = '大家好'");
  11. expression.getValue(sysUser);
  12. Console.log(sysUser);
  13. }
  14. }

方式3 - 表达式为赋值操作 - 动态
  1. public class DBTest {
  2. /**
  3. * 动态赋值
  4. */
  5. @Test
  6. public void test12_3() {
  7. SysUser sysUser = new SysUser();
  8. sysUser.setEmail("邮箱地址");
  9. SpelExpressionParser spelExpressionParser = new SpelExpressionParser();
  10. StandardEvaluationContext standardEvaluationContext = new StandardEvaluationContext();
  11. standardEvaluationContext.setVariable("newNickname", "大家好");
  12. Expression expression = spelExpressionParser.parseExpression("nickName = #newNickname");
  13. expression.getValue(standardEvaluationContext,sysUser);
  14. Console.log(sysUser);
  15. }
  16. }

1.1.5 调用某类的静态方法
方式1(不建议):1.1.2一样,用实例对象调静态方法
方式2(建议):格式=》T(类的全限定名).静态方法(实参)
  1. public class SpELTest {
  2. @Test
  3. public void test13() {
  4. SpelExpressionParser spelExpressionParser = new SpelExpressionParser();
  5. Expression expression = spelExpressionParser.parseExpression("T(java.lang.String).valueOf(5)");
  6. String value = expression.getValue(String.class);
  7. Console.log(value);
  8. Expression expression1 = spelExpressionParser.parseExpression("T(java.util.Arrays).asList(1,2,3,4)");
  9. List value1 = expression1.getValue(List.class);
  10. Console.log(value1);
  11. }
  12. }

方式3(建议):格式=》#context传入的方法Key(实参) - 方法2的简写 - 个人更建议(方法2)
  1. public class DBTest {
  2. @Test
  3. public void test15() {
  4. StandardEvaluationContext standardEvaluationContext = new StandardEvaluationContext();
  5. standardEvaluationContext.setVariable("addSuffixIfNot", ReflectUtil.getMethodByName(StrUtil.class,"addSuffixIfNot"));
  6. SpelExpressionParser spelExpressionParser = new SpelExpressionParser();
  7. Expression expression = spelExpressionParser.parseExpression("#addSuffixIfNot('name', '后缀')");
  8. Object value = expression.getValue(standardEvaluationContext);
  9. Console.log(value);
  10. }
  11. }

1.1.6 三元运算符
  1. public class DBTest {
  2. @Test
  3. public void test14() {
  4. SpelExpressionParser spelExpressionParser = new SpelExpressionParser();
  5. //简写的三元运算符
  6. StandardEvaluationContext standardEvaluationContext = new StandardEvaluationContext();
  7. standardEvaluationContext.setVariable("content", "发的范德萨发");
  8. standardEvaluationContext.setVariable("content2", null);
  9. Expression expression = spelExpressionParser.parseExpression("#content?:'无内容'");
  10. //Expression expression = spelExpressionParser.parseExpression("#content? #content:'无内容'"); //不可写成这样会报错,前面必须是java的布尔值类型
  11. Object value = expression.getValue(standardEvaluationContext);
  12. Console.log(value);
  13. expression = spelExpressionParser.parseExpression("#content2?:'无内容'");
  14. value = expression.getValue(standardEvaluationContext);
  15. Console.log(value);
  16. //标准的三元运算符
  17. expression = spelExpressionParser.parseExpression("T(cn.hutool.core.util.StrUtil).isNotBlank(#content2) ? #content2 : '无内容'");
  18. value = expression.getValue(standardEvaluationContext);
  19. Console.log(value);
  20. }
  21. }

1.1.7 容器(Iterable)- 选择符合条件的元素 - 格式=》容器.?[符合元素的条件]

介绍:类似Stream.filter作用

  1. public class DBTest {
  2. @Test
  3. public void test18() {
  4. List<SysUser> sysUsers = new ArrayList<>();
  5. sysUsers.add(new SysUser());
  6. IntStream.range(1,5).forEachOrdered(num -> {
  7. SysUser sysUser = new SysUser();
  8. sysUser.setEmail("邮箱" + num);
  9. sysUser.setId(String.valueOf(num));
  10. sysUsers.add(sysUser);
  11. });
  12. StandardEvaluationContext standardEvaluationContext = new StandardEvaluationContext();
  13. standardEvaluationContext.setVariable("sysUsers2", sysUsers);
  14. standardEvaluationContext.setVariable("sysUsers3", Collections.emptyList());
  15. standardEvaluationContext.setVariable("sysUsers4", null);
  16. SpelExpressionParser spelExpressionParser = new SpelExpressionParser();
  17. //下面四者等价,第三个可能会出现空指针问题
  18. Expression expression = spelExpressionParser.parseExpression("#root?.?[id > '3']");
  19. //Expression expression = spelExpressionParser.parseExpression("#root?.?[id > '3']");
  20. //Expression expression = spelExpressionParser.parseExpression("#root.?[id > '3']");
  21. //Expression expression = spelExpressionParser.parseExpression("?[id > '3']");
  22. List value = expression.getValue(sysUsers, List.class);
  23. Console.log(value);
  24. expression = spelExpressionParser.parseExpression("#sysUsers2?.?[email == '邮箱3']");
  25. value = expression.getValue(standardEvaluationContext, List.class);
  26. Console.log(value);
  27. expression = spelExpressionParser.parseExpression("#sysUsers3?.?[email == '邮箱3']");
  28. value = expression.getValue(standardEvaluationContext, List.class);
  29. Console.log(value);
  30. expression = spelExpressionParser.parseExpression("#sysUsers4?.?[email == '邮箱3']");
  31. value = expression.getValue(standardEvaluationContext, List.class);
  32. Console.log(value);
  33. }
  34. }

1.1.8 容器(Iterable)-字段投影 - 格式=》容器.![字段名]

介绍:类似Stream.map作用

  1. public class DBTest {
  2. @Test
  3. public void test17() {
  4. List<SysUser> sysUsers = new ArrayList<>();
  5. sysUsers.add(new SysUser());
  6. IntStream.range(1,5).forEachOrdered(num -> {
  7. SysUser sysUser = new SysUser();
  8. sysUser.setEmail("邮箱" + num);
  9. sysUsers.add(sysUser);
  10. });
  11. StandardEvaluationContext standardEvaluationContext = new StandardEvaluationContext();
  12. standardEvaluationContext.setVariable("sysUsers2", sysUsers);
  13. standardEvaluationContext.setVariable("sysUsers3", Collections.emptyList());
  14. standardEvaluationContext.setVariable("sysUsers4", null);
  15. SpelExpressionParser spelExpressionParser = new SpelExpressionParser();
  16. //下面四者等价,第三个可能会出现空指针异常问题
  17. Expression expression = spelExpressionParser.parseExpression("#this?.![email]");
  18. //Expression expression = spelExpressionParser.parseExpression("#root?.![email]");
  19. //Expression expression = spelExpressionParser.parseExpression("#root.![email]");
  20. //Expression expression = spelExpressionParser.parseExpression("![email]");
  21. List value = expression.getValue(sysUsers, List.class);
  22. Console.log(value);
  23. expression = spelExpressionParser.parseExpression("#sysUsers2?.![email]");
  24. value = expression.getValue(standardEvaluationContext, List.class);
  25. Console.log(value);
  26. expression = spelExpressionParser.parseExpression("#sysUsers3?.![email]");
  27. value = expression.getValue(standardEvaluationContext, List.class);
  28. Console.log(value);
  29. expression = spelExpressionParser.parseExpression("#sysUsers4?.![email]");
  30. value = expression.getValue(standardEvaluationContext, List.class);
  31. Console.log(value);
  32. }
  33. }

1.1.9 模板内容解析 - 仅解析 == #{}中括号里面的内容
  1. public class DBTest {
  2. @Test
  3. public void test19() {
  4. SpelExpressionParser spelExpressionParser = new SpelExpressionParser();
  5. //模板变量解析开始${ 待解析的内容 解析结束}
  6. TemplateParserContext templateParserContext = new TemplateParserContext();
  7. Expression expression = spelExpressionParser.parseExpression("你好我是你爸爸:#{#fatherName}",templateParserContext);
  8. StandardEvaluationContext standardEvaluationContext = new StandardEvaluationContext();
  9. standardEvaluationContext.setVariable("fatherName","Tom");
  10. Object value = expression.getValue(standardEvaluationContext);
  11. Console.log(value);
  12. }
  13. }

相关文章