个人站长还有什么类型的网站可以做,烟台网站建设方案策划,网站建设的个人条件,长沙市住房与城乡建设厅网站本文概览
欢迎阅读本文#xff0c;其中我们将深入探讨 Spring Expression Language#xff08;SpEL#xff09;的语法和实际应用。从基础概念到高级用法#xff0c;我们将在本文中了解如何使用 SpEL 提高代码的灵活性和表达力。无论大家是初学者还是有经验的开发者#x…本文概览
欢迎阅读本文其中我们将深入探讨 Spring Expression LanguageSpEL的语法和实际应用。从基础概念到高级用法我们将在本文中了解如何使用 SpEL 提高代码的灵活性和表达力。无论大家是初学者还是有经验的开发者本文将为大家提供深入了解 SpEL 的机会使大家能够在 Spring 项目中更好地利用这一强大的表达式语言。
文章涉及到的示例代码: guide-spring
语法详解
字面量表达式
SpEL 支持以下字面量表达式:
字符串 (String)数值: 整数 int or long 类型十六进制 int or long 类型以及浮点类型 float or double布尔值: true or false空对象 : null
示例:
package com.markus.spring.expression.language.reference;import org.springframework.expression.ExpressionParser;
import org.springframework.expression.spel.standard.SpelExpressionParser;/*** author: markus* date: 2024/1/21 8:46 PM* Description:* Blog: https://markuszhang.com* Its my honor to share what Ive learned with you!*/
public class LiteralExpressions {public static void main(String[] args) {ExpressionParser parser new SpelExpressionParser();// 解析 字符串String value parser.parseExpression(Hello,Literal Expression).getValue(String.class);System.out.println(value);// 解析 数值 int long float doubledouble number parser.parseExpression(4.5).getValue(double.class);System.out.println(number);// 解析 布尔值 true or falseboolean bool parser.parseExpression(true).getValue(boolean.class);System.out.println(bool);// 解析 空对象 nullObject obj parser.parseExpression(null).getValue();System.out.println(obj);}
}
执行结果: 属性表达式
在 SpEL 表达式中我们可以通过 属性名 来获取对应路径的内容如果涉及到嵌套属性我们用 ‘.’ 来表示级联关系。
示例:
package com.markus.spring.expression.language.reference;import com.markus.spring.expression.language.Inventor;
import com.markus.spring.expression.language.InventorBuilder;
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: markus* date: 2024/1/21 8:59 PM* Description:* Blog: https://markuszhang.com* Its my honor to share what Ive learned with you!*/
public class PropertiesExpression {public static void main(String[] args) {Inventor inventor InventorBuilder.builder();EvaluationContext context new StandardEvaluationContext(inventor);ExpressionParser parser new SpelExpressionParser();String name parser.parseExpression(name).getValue(context, String.class);System.out.println(name);// nested propertyint length parser.parseExpression(name.length).getValue(context, int.class);System.out.println(length);}
}执行结果: 容器表达式
这里的容器用于表示 数组(Array)、集合(List)、字典(Map)我们统一来看下有关于这些内容的 SpEL 表达式都有哪些
Array
索引获取通过方括号[index]来获取目标索引值数组构造包括基本类型构造、复杂类型构造
示例:
package com.markus.spring.expression.language.reference;import com.markus.spring.expression.language.Inventor;
import com.markus.spring.expression.language.InventorBuilder;
import org.springframework.expression.EvaluationContext;
import org.springframework.expression.ExpressionParser;
import org.springframework.expression.spel.standard.SpelExpressionParser;
import org.springframework.expression.spel.support.StandardEvaluationContext;import java.util.Arrays;/*** author: markus* date: 2024/1/21 9:10 PM* Description: 数组相关的表达式示例* Blog: https://markuszhang.com* Its my honor to share what Ive learned with you!*/
public class ArraysExpression {public static void main(String[] args) {ExpressionParser parser new SpelExpressionParser();// arrayInventor[] inventors {InventorBuilder.builder()};EvaluationContext context new StandardEvaluationContext(inventors);// index 表达Inventor inventor parser.parseExpression([0]).getValue(context, Inventor.class);System.out.println(inventor);// index nested propertyString name parser.parseExpression([0].name).getValue(context, String.class);System.out.println(name);// index nested property indexinventor.getBooleans().add(true);boolean bool parser.parseExpression([0].booleans[0]).getValue(context, boolean.class);System.out.println(bool);// array constructionint[] numbers parser.parseExpression(new int[]{1,2,3}).getValue(context, int[].class);for (int number : numbers) {System.out.print(number );}System.out.println();// complex type arrays constructorInventor[] complexTypeArrays parser.parseExpression(new com.markus.spring.expression.language.Inventor[1]).getValue(context, Inventor[].class);complexTypeArrays[0] InventorBuilder.builder();Arrays.stream(complexTypeArrays).forEach(System.out::println);}
}List
集合和数组的数据访问以及嵌套属性访问的方式一致示例可以参考 Array 实现。我们额外补充些有关 List 的示例
package com.markus.spring.expression.language.reference;import com.markus.spring.expression.language.Inventor;
import com.markus.spring.expression.language.InventorBuilder;
import org.springframework.expression.EvaluationContext;
import org.springframework.expression.ExpressionParser;
import org.springframework.expression.spel.standard.SpelExpressionParser;
import org.springframework.expression.spel.support.StandardEvaluationContext;import java.util.ArrayList;
import java.util.List;/*** author: markus* date: 2024/1/21 9:32 PM* Description: List 集合有关 SpEL 表达式的示例* Blog: https://markuszhang.com* Its my honor to share what Ive learned with you!*/
public class ListExpression {public static void main(String[] args) {Inventor inventor InventorBuilder.builder();ListInventor inventors new ArrayList();inventors.add(inventor);EvaluationContext context new StandardEvaluationContext(inventors);ExpressionParser parser new SpelExpressionParser();// by [index] get elementInventor inventorFromParser parser.parseExpression([0]).getValue(context, Inventor.class);System.out.println(inventorFromParser);// inline list// 1. simple typeSuppressWarnings(unchecked)ListInteger integers parser.parseExpression({1,2,3,4,5}).getValue(context, List.class);System.out.println(integers);// 2. complex typeSuppressWarnings(unchecked)ListInventor inventorList (ListInventor) parser.parseExpression({T(com.markus.spring.expression.language.InventorBuilder).builder()}).getValue(context);System.out.println(inventorList);}
}执行结果: Map
Map中的数据访问有些不同示例如下所示:
package com.markus.spring.expression.language.reference;import com.markus.spring.expression.language.Inventor;
import com.markus.spring.expression.language.InventorBuilder;
import org.springframework.expression.EvaluationContext;
import org.springframework.expression.ExpressionParser;
import org.springframework.expression.spel.standard.SpelExpressionParser;
import org.springframework.expression.spel.support.StandardEvaluationContext;import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;/*** author: markus* date: 2024/1/21 9:47 PM* Description:* Blog: https://markuszhang.com* Its my honor to share what Ive learned with you!*/
public class MapExpression {public static void main(String[] args) {Inventor inventor InventorBuilder.builder();MapString, Inventor map new HashMap();map.put(markus, inventor);EvaluationContext context new StandardEvaluationContext(map);ExpressionParser parser new SpelExpressionParser();// by [key] get elementInventor inventorFromParser parser.parseExpression([markus]).getValue(context, Inventor.class);System.out.println(inventorFromParser);// nested property accessString name parser.parseExpression([markus].name).getValue(context, String.class);System.out.println(name);// inline mapSuppressWarnings(unchecked)MapString, Inventor inventorMap parser.parseExpression({markus:T(com.markus.spring.expression.language.InventorBuilder).builder()}).getValue(context, Map.class);System.out.println(inventorMap);}
}
执行结果: 方法调用表达式
示例如下:
package com.markus.spring.expression.language.reference;import org.springframework.expression.ExpressionParser;
import org.springframework.expression.spel.standard.SpelExpressionParser;/*** author: markus* date: 2024/1/21 9:55 PM* Description: 方法调用表达式的示例* Blog: https://markuszhang.com* Its my honor to share what Ive learned with you!*/
public class MethodInvokeExpression {public static void main(String[] args) {ExpressionParser parser new SpelExpressionParser();String subString parser.parseExpression(Hello,SpEL.substring(0,5)).getValue(String.class);System.out.println(subString);}
}执行结果: 运算符表达式
SpEL 表达式支持如下运算法:
关系运算符逻辑运算符算术运算符赋值运算符
示例如下:
package com.markus.spring.expression.language.reference;import org.springframework.expression.ExpressionParser;
import org.springframework.expression.spel.standard.SpelExpressionParser;/*** author: markus* date: 2024/1/21 10:00 PM* Description: 运算符 SpEL 示例* Blog: https://markuszhang.com* Its my honor to share what Ive learned with you!*/
public class OperatorsExpression {/*** more demo please reference https://docs.spring.io/spring-framework/reference/core/expressions/language-ref/operators.html** param args*/public static void main(String[] args) {ExpressionParser parser new SpelExpressionParser();// first : relational operatorsboolean result parser.parseExpression(2 5).getValue(Boolean.class);System.out.println(2 5 : result);result parser.parseExpression(2 5).getValue(Boolean.class);System.out.println(2 5 : result);result parser.parseExpression(1 instanceof T(int)).getValue(Boolean.class);System.out.println(1 instanceof T(int) : result);result parser.parseExpression(1 instanceof T(Integer)).getValue(Boolean.class);System.out.println(1 instanceof T(Integer) : result);// second : logical operators// and ()// or (||)// not (!)result parser.parseExpression(true or false).getValue(Boolean.class);System.out.println(true or false : result);result parser.parseExpression(true and false).getValue(Boolean.class);System.out.println(true and false : result);result parser.parseExpression(!true).getValue(Boolean.class);System.out.println(!true : result);// third : mathematical operators// - * / %// Additionint two parser.parseExpression(1 1).getValue(Integer.class); // 2System.out.println(1 1 : two);String testString parser.parseExpression(test string).getValue(String.class); // test stringSystem.out.println(test string : testString);// Subtractionint four parser.parseExpression(1 - -3).getValue(Integer.class); // 4System.out.println(1 - -3 : four);double d parser.parseExpression(1000.00 - 1e4).getValue(Double.class); // -9000System.out.println(1000.00 - 1e4 : d);// Multiplicationint six parser.parseExpression(-2 * -3).getValue(Integer.class); // 6System.out.println(-2 * -3 : six);double twentyFour parser.parseExpression(2.0 * 3e0 * 4).getValue(Double.class); // 24.0System.out.println(2.0 * 3e0 * 4 : twentyFour);// Divisionint minusTwo parser.parseExpression(6 / -3).getValue(Integer.class); // -2System.out.println(6 / -3 : minusTwo);double oneD parser.parseExpression(8.0 / 4e0 / 2).getValue(Double.class); // 1.0System.out.println(8.0 / 4e0 / 2 : oneD);// Modulusint three parser.parseExpression(7 % 4).getValue(Integer.class); // 3System.out.println(7 % 4 : three);int one parser.parseExpression(8 / 5 % 2).getValue(Integer.class); // 1System.out.println(8 / 5 % 2 : one);// Operator precedenceint minusTwentyOne parser.parseExpression(12-3*8).getValue(Integer.class); // -21System.out.println(12-3*8 : minusTwentyOne);}
}执行结果: 类型表达式
我们可以通过 T(xxx) 来表示 Class 的实例静态方法也可以通过这个方式使用前面我们已经展示过即 T(xxx).method(xxx)另外值得注意的是在java.lang包下的类可以不指定全限定名直接指定类名。
示例如下:
package com.markus.spring.expression.language.reference;import org.springframework.expression.ExpressionParser;
import org.springframework.expression.spel.standard.SpelExpressionParser;/*** author: markus* date: 2024/1/21 10:25 PM* Description: 类型 相关的 SpEL 示例* Blog: https://markuszhang.com* Its my honor to share what Ive learned with you!*/
public class TypeExpression {public static void main(String[] args) {ExpressionParser parser new SpelExpressionParser();Class dateClass parser.parseExpression(T(java.util.Date)).getValue(Class.class);System.out.println(dateClass);Class stringClass parser.parseExpression(T(String)).getValue(Class.class);System.out.println(stringClass);boolean trueValue parser.parseExpression(T(java.math.RoundingMode).CEILING T(java.math.RoundingMode).FLOOR).getValue(Boolean.class);System.out.println(trueValue);}
}执行结果: 构造器表达式
通过 SpEL 来初始化实例使用时必须要指定全限定名包括 java.lang 包下的
示例如下:
package com.markus.spring.expression.language.reference;import com.markus.spring.expression.language.Inventor;
import org.springframework.expression.ExpressionParser;
import org.springframework.expression.spel.standard.SpelExpressionParser;/*** author: markus* date: 2024/1/21 10:31 PM* Description: 构造器 SpEL 示例* Blog: https://markuszhang.com* Its my honor to share what Ive learned with you!*/
public class ConstructorExpression {public static void main(String[] args) {ExpressionParser parser new SpelExpressionParser();Inventor einstein parser.parseExpression(new com.markus.spring.expression.language.Inventor()).getValue(Inventor.class);System.out.println(einstein);}
}执行结果: 变量表达式
我们可以在 SpEL 中通过使用 #variableName 来获取执行的变量值。另外 变量的表示形式必须按照以下要求(至少有以下1个组成)
A-Z 和 a-z0-9_$
示例如下:
package com.markus.spring.expression.language.reference;import com.markus.spring.expression.language.Inventor;
import com.markus.spring.expression.language.InventorBuilder;
import org.springframework.expression.EvaluationContext;
import org.springframework.expression.ExpressionParser;
import org.springframework.expression.spel.standard.SpelExpressionParser;
import org.springframework.expression.spel.support.SimpleEvaluationContext;
import org.springframework.expression.spel.support.StandardEvaluationContext;import java.util.ArrayList;
import java.util.List;/*** author: markus* date: 2024/1/21 10:35 PM* Description: 变量 SpEL 表达式示例* Blog: https://markuszhang.com* Its my honor to share what Ive learned with you!*/
public class VariableExpression {public static void main(String[] args) {Inventor inventor InventorBuilder.builder();inventor.getBooleans().add(true);inventor.getBooleans().add(false);EvaluationContext context SimpleEvaluationContext.forReadWriteDataBinding().build();context.setVariable(newName, Luna);ExpressionParser parser new SpelExpressionParser();parser.parseExpression(name #newName).getValue(context, inventor);System.out.println(inventor);// #this and #root// #this 总是指向当前表达式中计算的对象// #root 总是指向根对象ListInteger integers new ArrayList();integers.add(1);integers.add(2);integers.add(3);integers.add(4);integers.add(5);integers.add(6);context.setVariable(integers, integers);String thisExpression #integers.?[#this 3];SuppressWarnings(unchecked)ListInteger gt3List parser.parseExpression(thisExpression).getValue(context, List.class);gt3List.forEach(integer - System.out.print(integer ));System.out.println();// #rootcontext new StandardEvaluationContext(inventor);Inventor value parser.parseExpression(#root).getValue(context, Inventor.class);System.out.println(value);}
}执行结果: 函数表达式
我们可以向 EvaluationContext中注册函数并在 SpEL 中使用
示例如下:
package com.markus.spring.expression.language.reference;import com.markus.spring.expression.language.InventorBuilder;
import org.springframework.expression.EvaluationContext;
import org.springframework.expression.ExpressionParser;
import org.springframework.expression.spel.standard.SpelExpressionParser;
import org.springframework.expression.spel.support.SimpleEvaluationContext;import java.lang.reflect.Method;
import java.util.Objects;/*** author: markus* date: 2024/1/21 10:54 PM* Description: 注册方法 并在 SpEL 中使用 示例* Blog: https://markuszhang.com* Its my honor to share what Ive learned with you!*/
public class MethodExpression {// must be static methodpublic static void display(Object obj) {System.out.println(obj);}public static void main(String[] args) throws NoSuchMethodException {Method method MethodExpression.class.getDeclaredMethod(display, Object.class);EvaluationContext context SimpleEvaluationContext.forReadWriteDataBinding().build();context.setVariable(display, method);context.setVariable(inventor, InventorBuilder.builder());ExpressionParser parser new SpelExpressionParser();parser.parseExpression(#display(#inventor)).getValue(context);}
}执行结果: Bean 引用表达式
通过 xxx 来获取 Spring 容器中的 Bean 实例
示例如下:
package com.markus.spring.expression.language.reference;import com.markus.spring.expression.language.Inventor;
import org.springframework.context.expression.BeanFactoryResolver;
import org.springframework.context.support.ClassPathXmlApplicationContext;
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: markus* date: 2024/1/21 11:00 PM* Description: Bean 应用示例* Blog: https://markuszhang.com* Its my honor to share what Ive learned with you!*/
public class BeanReferenceExpression {public static void main(String[] args) {ClassPathXmlApplicationContext context new ClassPathXmlApplicationContext(classpath:/META-INF/expression-in-bean-definitions.xml);BeanFactoryResolver beanFactoryResolver new BeanFactoryResolver(context.getBeanFactory());StandardEvaluationContext evaluationContext new StandardEvaluationContext();evaluationContext.setBeanResolver(beanFactoryResolver);ExpressionParser parser new SpelExpressionParser();String expression inventor;Inventor inventor parser.parseExpression(expression).getValue(evaluationContext, Inventor.class);System.out.println(inventor);}
}
执行结果: 三元表达式
我们还可以在表达式内部使用三元运算符执行if-then-else条件逻辑。
package com.markus.spring.expression.language.reference;import com.markus.spring.expression.language.Inventor;
import org.springframework.expression.ExpressionParser;
import org.springframework.expression.spel.standard.SpelExpressionParser;/*** author: markus* date: 2024/1/21 11:07 PM* Description: 三元表达式 示例* Blog: https://markuszhang.com* Its my honor to share what Ive learned with you!*/
public class TernaryOperatorExpression {public static void main(String[] args) {ExpressionParser parser new SpelExpressionParser();String falseString parser.parseExpression(false ? trueExp : falseExp).getValue(String.class);System.out.println(false ? trueExp : falseExp : falseString);// The Elvis operator (精简版 三元表达式)String name parser.parseExpression(name?:Unknown).getValue(new Inventor(), String.class);System.out.println(name); // Unknown}
}
执行结果: 安全指针表达式
为避免出现空指针我们还可以在 SpEL 中使用 ?.来实现
示例如下:
package com.markus.spring.expression.language.reference;import com.markus.spring.expression.language.Inventor;
import org.springframework.expression.EvaluationContext;
import org.springframework.expression.ExpressionParser;
import org.springframework.expression.spel.standard.SpelExpressionParser;
import org.springframework.expression.spel.support.SimpleEvaluationContext;/*** author: markus* date: 2024/1/21 11:11 PM* Description: 安全指针示例* Blog: https://markuszhang.com* Its my honor to share what Ive learned with you!*/
public class SafeNavigationOperators {public static void main(String[] args) {ExpressionParser parser new SpelExpressionParser();EvaluationContext context SimpleEvaluationContext.forReadOnlyDataBinding().build();Inventor inventor new Inventor();inventor.setName(markus zhang);context.setVariable(inventor, inventor);String name parser.parseExpression(#inventor.name?.#inventor.name).getValue(context, String.class);System.out.println(name); // markus zhanginventor.setName(null);name parser.parseExpression(#inventor.name?.#inventor.name).getValue(context, String.class);System.out.println(name); // null - does not throw NullPointerException!!!}
}执行结果: 集合筛选表达式
Selection是一种强大的表达语言功能它允许您通过从其条目中进行选择将源集合转换为另一个集合。选择使用的语法是.?[selectionExpression]。它过滤集合并返回一个包含原始元素子集的新集合。
示例如下:
package com.markus.spring.expression.language.reference;import com.markus.spring.expression.language.Inventor;
import org.springframework.expression.EvaluationContext;
import org.springframework.expression.ExpressionParser;
import org.springframework.expression.spel.standard.SpelExpressionParser;
import org.springframework.expression.spel.support.StandardEvaluationContext;import java.util.ArrayList;
import java.util.List;/*** author: markus* date: 2024/1/21 11:17 PM* Description: 集合元素选择 示例* Blog: https://markuszhang.com* Its my honor to share what Ive learned with you!*/
public class CollectionSelectionExpression {public static void main(String[] args) {EvaluationContext context new StandardEvaluationContext();ListInteger integers new ArrayList();integers.add(1);integers.add(2);integers.add(3);integers.add(4);integers.add(5);integers.add(6);context.setVariable(integers, integers);ExpressionParser parser new SpelExpressionParser();SuppressWarnings(unchecked)ListInteger list (ListInteger) parser.parseExpression(#integers.?[#this 3 || #this 4]).getValue(context);list.forEach(ele - {System.out.print(ele );});}
}执行结果: 集合子集表达式
集合子集 意为 获取目标集合中某一字段集合示例如下:
package com.markus.spring.expression.language.reference;import com.markus.spring.expression.language.Inventor;
import com.markus.spring.expression.language.InventorBuilder;
import org.springframework.expression.EvaluationContext;
import org.springframework.expression.ExpressionParser;
import org.springframework.expression.spel.standard.SpelExpressionParser;
import org.springframework.expression.spel.support.StandardEvaluationContext;import java.util.ArrayList;
import java.util.List;/*** author: markus* date: 2024/1/21 11:17 PM* Description: 集合元素选择 示例* Blog: https://markuszhang.com* Its my honor to share what Ive learned with you!*/
public class CollectionProjectionExpression {public static void main(String[] args) {EvaluationContext context new StandardEvaluationContext();ListInventor inventors new ArrayList();inventors.add(InventorBuilder.builder());inventors.add(InventorBuilder.builder(Luna));context.setVariable(inventors, inventors);ExpressionParser parser new SpelExpressionParser();SuppressWarnings(unchecked)ListString list (ListString) parser.parseExpression(#inventors.![name]).getValue(context);list.forEach(ele - {System.out.println(ele );});}
}执行结果: 模板表达式
表达式执行一个模板并在这个模板中通过 #{} 来占位示例如下:
package com.markus.spring.expression.language.reference;import org.springframework.expression.ExpressionParser;
import org.springframework.expression.ParserContext;
import org.springframework.expression.spel.standard.SpelExpressionParser;/*** author: markus* date: 2024/1/21 11:29 PM* Description:* Blog: https://markuszhang.com* Its my honor to share what Ive learned with you!*/
public class TemplateExpression {public static void main(String[] args) {ExpressionParser parser new SpelExpressionParser();String randomPhrase parser.parseExpression(random number is #{T(java.lang.Math).random()},new TemplateParserContext()).getValue(String.class);System.out.println(random number is #{T(java.lang.Math).random()} : randomPhrase);}public static class TemplateParserContext implements ParserContext {public String getExpressionPrefix() {return #{;}public String getExpressionSuffix() {return };}public boolean isTemplate() {return true;}}
}执行结果: 本文总结
通过本文我们详细讨论了 SpEL 的语法、特性和应用场景。从简单的字面量表达式到复杂的类型引用相信大家已经掌握了在 Spring 项目中灵活使用 SpEL 的关键知识。在总结中不要忘记不断实践和深入研究以便更好地运用 SpEL 提高代码的可读性和可维护性。感谢您的阅读希望大家在今后的项目中充分发挥 SpEL 的潜力