Spring

您所在的位置:网站首页 cause怎么拼 Spring

Spring

2024-07-16 23:14| 来源: 网络整理| 查看: 265

文章目录 一、概述1、什么是SpEL2、SpEL能做什么 二、SpEL表达式使用0、用到的类1、文字表达式2、属性, 数组, List, Map,和 索引(1)属性操作(2)数组和List(3)Map 3、内嵌List4、内嵌Map5、构建数组6、调用类的方法7、SpEL操作符(1)标准运算符(2)instanceof 和 正则表达式的匹配操作符(3)操作符的英文等价标识(4)逻辑运算符(5)数学运算符(6)赋值运算符 8、获取类的类型9、调用类构造器10、SpEL变量(1)基本使用(2)#this 和 #root变量 11、调用类静态方法12、Bean引用13、三元运算符(If-Then-Else)14、Elvis操作符15、安全导航操作员16、集合选择17、集合投影18、表达式模板 参考资料

一、概述 1、什么是SpEL

SpEL(Spring Expression Language)是Spring框架中用于表达式语言的一种方式。它类似于其他编程语言中的表达式语言,用于在运行时计算值或执行特定任务。

SpEL提供了一种简单且强大的方式来访问和操作对象的属性、调用对象的方法,以及实现运算、条件判断等操作。它可以被用于XML和注解配置中,可以用于许多Spring框架中的特性,如依赖注入、AOP、配置文件等。

SpEL表达式可以在字符串中进行定义,使用特殊的语法和符号来表示特定的操作。例如,可以使用${expression}来表示一个SpEL表达式,其中expression是具体的SpEL语句。

SpEL支持各种操作和函数,包括算术运算、逻辑运算、条件判断、正则表达式匹配、集合操作等。它还支持访问上下文中的变量和参数,以及调用对象的方法。

2、SpEL能做什么

SpEL表达式具有广泛的功能,以下是一些SpEL表达式可以做的事情:

访问对象属性:SpEL表达式可以通过对象引用来访问对象的属性,例如${object.property}。调用方法:SpEL表达式可以调用对象的方法,例如${objecthod()}。进行算术运算:SpEL表达式支持各种算术运算符,如加法、减法、乘法和除法。进行逻辑运算:SpEL表达式支持逻辑运算符,如与、或、非等。进行条件判断:SpEL表达式可以进行条件判断,例如通过if语句判断条件,并执行相应的操作。访问集合元素和属性:SpEL表达式可以通过索引或键来访问集合中的元素或对象的属性。执行正则表达式匹配:SpEL表达式可以执行正则表达式匹配,并返回匹配结果。访问上下文变量和参数:SpEL表达式可以访问上下文中的变量和方法参数。进行类型转换:SpEL表达式可以进行类型转换操作,将一个对象转换为另一种类型。支持特殊操作符:SpEL表达式支持一些特殊的操作符,如Elvis操作符(?:)、安全导航操作符(?.)等。

总的来说,SpEL表达式可以用于在运行时计算值、执行任务和操作对象,提供了灵活且强大的表达能力,广泛应用于Spring框架中的各种功能和配置中。

二、SpEL表达式使用 0、用到的类 public class PlaceOfBirth { private String city; private String country; public PlaceOfBirth(String city) { this.city=city; } public PlaceOfBirth(String city, String country) { this(city); this.country = country; } public String getCity() { return city; } public void setCity(String s) { this.city = s; } public String getCountry() { return country; } public void setCountry(String country) { this.country = country; } } import java.util.*; public class Society { private String name; public static String Advisors = "advisors"; public static String President = "president"; private List members = new ArrayList(); private Map officers = new HashMap(); public List getMembers() { return members; } public Map getOfficers() { return officers; } public String getName() { return name; } public void setName(String name) { this.name = name; } public boolean isMember(String name) { for (Inventor inventor : members) { if (inventor.getName().equals(name)) { return true; } } return false; } } import java.util.Date; import java.util.GregorianCalendar; public class Inventor { private String name; private String nationality; private String[] inventions; private Date birthdate; private PlaceOfBirth placeOfBirth; public Inventor(String name, String nationality) { GregorianCalendar c= new GregorianCalendar(); this.name = name; this.nationality = nationality; this.birthdate = c.getTime(); } public Inventor(String name, Date birthdate, String nationality) { this.name = name; this.nationality = nationality; this.birthdate = birthdate; } public Inventor() { } public String getName() { return name; } public void setName(String name) { this.name = name; } public String getNationality() { return nationality; } public void setNationality(String nationality) { this.nationality = nationality; } public Date getBirthdate() { return birthdate; } public void setBirthdate(Date birthdate) { this.birthdate = birthdate; } public PlaceOfBirth getPlaceOfBirth() { return placeOfBirth; } public void setPlaceOfBirth(PlaceOfBirth placeOfBirth) { this.placeOfBirth = placeOfBirth; } public void setInventions(String[] inventions) { this.inventions = inventions; } public String[] getInventions() { return inventions; } } 1、文字表达式

支持的文字表达式类型有字符串、数值(int、real、hex)、布尔和null。字符串由单引号分隔。若要将单引号本身放在字符串中,请使用两个单引号字符。

通常来说,不会单纯的定义一个简单的文字表达式,而是通过方法调用等等复杂的操作,来完成一个功能:

// 定义Parser,可以定义全局的parser ExpressionParser parser = new SpelExpressionParser(); // 获取字符串 "Hello World" String helloWorld = (String) parser.parseExpression("'Hello World'").getValue(); // double类型 6.0221415E23 double avogadrosNumber = (Double) parser.parseExpression("6.0221415E+23").getValue(); // int类型 2147483647 int maxValue = (Integer) parser.parseExpression("0x7FFFFFFF").getValue(); // true boolean trueValue = (Boolean) parser.parseExpression("true").getValue(); // null Object nullValue = parser.parseExpression("null").getValue(); 2、属性, 数组, List, Map,和 索引 (1)属性操作

注意!属性名的第一个字母不区分大小写。

// 定义Parser,可以定义全局的parser ExpressionParser parser = new SpelExpressionParser(); // 注意!属性名的第一个字母不区分大小写。 birthdate.year等效于Birthdate.Year // 取出Inventor 中,birthdate属性的year属性 Inventor zhangsan = new Inventor("zhangsan", new Date(), "China"); // 定义StandardEvaluationContext ,传入一个操作对象 StandardEvaluationContext zhangsanContext = new StandardEvaluationContext(zhangsan); int year = (Integer) parser.parseExpression("birthdate.year + 1900").getValue(zhangsanContext); System.out.println(year); // 2023 //取出Inventor的placeOfBirth的city属性 PlaceOfBirth placeOfBirth = new PlaceOfBirth("长沙", "中国"); zhangsan.setPlaceOfBirth(placeOfBirth); String city = (String) parser.parseExpression("placeOfBirth.City").getValue(zhangsanContext); System.out.println(city); // 长沙 (2)数组和List

数组和List的内容是通过使用方括号符号获得的。

// 定义Parser,可以定义全局的parser ExpressionParser parser = new SpelExpressionParser(); EvaluationContext context = SimpleEvaluationContext.forReadOnlyDataBinding().build(); // 省略数据初始化 // 取出tesla对象的inventions 第四个数据 String invention = parser.parseExpression("inventions[3]").getValue( context, tesla, String.class); // 取出ieee对象的第一个Member的name属性 String name = parser.parseExpression("Members[0].Name").getValue( context, ieee, String.class); // 取出ieee对象的第一个Member中的第七个Inventions String invention = parser.parseExpression("Members[0].Inventions[6]").getValue( context, ieee, String.class); (3)Map

Map操作是通过key来获取的

// 取出societyContext的Officers中的key为president的值 Inventor pupin = parser.parseExpression("Officers['president']").getValue( societyContext, Inventor.class); String city = parser.parseExpression("Officers['president'].PlaceOfBirth.City").getValue( societyContext, String.class); // Officers中key为advisors的值取第一个 parser.parseExpression("Officers['advisors'][0].PlaceOfBirth.Country").setValue( societyContext, "Croatia"); 3、内嵌List

可以使用{}符号在表达式中直接表示List。{}本身意味着一个空列表。

// 定义Parser,可以定义全局的parser ExpressionParser parser = new SpelExpressionParser(); EvaluationContext context = SimpleEvaluationContext.forReadOnlyDataBinding().build(); // [1, 2, 3, 4] List numbers = (List) parser.parseExpression("{1,2,3,4}").getValue(context); System.out.println(numbers); // 嵌套: [[a, b], [x, y]] List listOfLists = (List) parser.parseExpression("{{'a','b'},{'x','y'}}").getValue(context); System.out.println(listOfLists); 4、内嵌Map

使用{key:value}符号在表达式中表示Map。{:}意味着空Map。

// 定义Parser,可以定义全局的parser ExpressionParser parser = new SpelExpressionParser(); EvaluationContext context = SimpleEvaluationContext.forReadOnlyDataBinding().build(); // {name=Nikola, dob=10-July-1856} Map inventorInfo = (Map) parser.parseExpression("{name:'Nikola',dob:'10-July-1856'}").getValue(context); System.out.println(inventorInfo); // 嵌套:{name={first=Nikola, last=Tesla}, dob={day=10, month=July, year=1856}} Map mapOfMaps = (Map) parser.parseExpression("{name:{first:'Nikola',last:'Tesla'},dob:{day:10,month:'July',year:1856}}").getValue(context); System.out.println(mapOfMaps); // List与Map可以嵌套使用,互相结合。 // 嵌套:[{name={first=Nikola, last=Tesla}}, {dob={day=10, month=July, year=1856}}] List listOfMaps = (List) parser.parseExpression("{{name:{first:'Nikola',last:'Tesla'}},{dob:{day:10,month:'July',year:1856}}}").getValue(context); System.out.println(listOfMaps); 5、构建数组

多维数组不提供初始化方式。

// 定义Parser,可以定义全局的parser ExpressionParser parser = new SpelExpressionParser(); EvaluationContext context = SimpleEvaluationContext.forReadOnlyDataBinding().build(); int[] numbers1 = (int[]) parser.parseExpression("new int[4]").getValue(context); // 数组并初始化 int[] numbers2 = (int[]) parser.parseExpression("new int[]{1,2,3}").getValue(context); // 多维数组 int[][] numbers3 = (int[][]) parser.parseExpression("new int[4][5]").getValue(context); 6、调用类的方法 ExpressionParser parser = new SpelExpressionParser(); // 调用substring方法 String bc = parser.parseExpression("'abc'.substring(1, 3)").getValue(String.class); // 调用societyContext中对象的isMember方法,并传值。 StandardEvaluationContext societyContext = new StandardEvaluationContext(society); boolean isMember = parser.parseExpression("isMember('Mihajlo Pupin')").getValue( societyContext, Boolean.class); 7、SpEL操作符 (1)标准运算符

使用标准运算符表示法支持关系运算符(等于、不等于、小于、小于或等于、大于和大于或等于)。

null不被视为任何东西(即不为零)。因此,任何其他值总是大于null (X > null总是为真),并且没有任何其他值小于零(X < null总是为假)。

ExpressionParser parser = newSpelExpressionParser(); // evaluates to true boolean trueValue = parser.parseExpression("2 == 2").getValue(Boolean.class); // evaluates to false boolean falseValue = parser.parseExpression("2 < -5.0").getValue(Boolean.class); // evaluates to true boolean trueValue = parser.parseExpression("'black' < 'block'").getValue(Boolean.class); (2)instanceof 和 正则表达式的匹配操作符

使用基本类型时要小心,因为它们会立即被装箱为包装器类型,所以1 instanceof T(int)会计算为false,而1 instanceof T(Integer)会计算为true。

// evaluates to false boolean falseValue = parser.parseExpression( "'xyz' instanceof T(Integer)").getValue(Boolean.class); // evaluates to true boolean trueValue = parser.parseExpression( "'5.00' matches '^-?\\d+(\\.\\d{2})?$'").getValue(Boolean.class); //evaluates to false boolean falseValue = parser.parseExpression( "'5.0067' matches '^-?\\d+(\\.\\d{2})?$'").getValue(Boolean.class); (3)操作符的英文等价标识

每个符号操作符也可以被指定为纯字母的等价物。这避免了所使用的符号对于嵌入表达式的文档类型具有特殊含义的问题(例如在XML文档中)。所有文本操作符都不区分大小写。对应的文本是: lt () le (=) eq (==) ne (!=) div (/) mod (%) not (!)

(4)逻辑运算符

SpEL支持以下逻辑运算符:and、or、not

// 结果: false boolean falseValue = parser.parseExpression("true and false").getValue(Boolean.class); // 调用方法并根据方法返回值判断 String expression = "isMember('Nikola Tesla') and isMember('Mihajlo Pupin')"; boolean trueValue = parser.parseExpression(expression).getValue(societyContext, Boolean.class); // -- OR -- boolean trueValue = parser.parseExpression("true or false").getValue(Boolean.class); // 调用方法并根据方法返回值判断 String expression = "isMember('Nikola Tesla') or isMember('Albert Einstein')"; boolean trueValue = parser.parseExpression(expression).getValue(societyContext, Boolean.class); // -- NOT -- // 取反 boolean falseValue = parser.parseExpression("!true").getValue(Boolean.class); // -- AND and NOT -- String expression = "isMember('Nikola Tesla') and !isMember('Mihajlo Pupin')"; boolean falseValue = parser.parseExpression(expression).getValue(societyContext, Boolean.class); (5)数学运算符

可以对数字和字符串使用加法运算符。 只能对数字使用减法、乘法和除法运算符。 也可以使用模数(%)和指数幂(^)运算符。 强制执行标准运算符优先级。

// Addition int two = parser.parseExpression("1 + 1").getValue(Integer.class); // 2 String testString = parser.parseExpression( "'test' + ' ' + 'string'").getValue(String.class); // 'test string' // Subtraction int four = parser.parseExpression("1 - -3").getValue(Integer.class); // 4 double d = parser.parseExpression("1000.00 - 1e4").getValue(Double.class); // -9000 // Multiplication int six = parser.parseExpression("-2 * -3").getValue(Integer.class); // 6 double twentyFour = parser.parseExpression("2.0 * 3e0 * 4").getValue(Double.class); // 24.0 // Division int minusTwo = parser.parseExpression("6 / -3").getValue(Integer.class); // -2 double one = parser.parseExpression("8.0 / 4e0 / 2").getValue(Double.class); // 1.0 // Modulus int three = parser.parseExpression("7 % 4").getValue(Integer.class); // 3 int one = parser.parseExpression("8 / 5 % 2").getValue(Integer.class); // 1 // Operator precedence int minusTwentyOne = parser.parseExpression("1+2-3*8").getValue(Integer.class); // -21 (6)赋值运算符

若要给对象设置属性,请使用赋值运算符(=)。这通常在对setValue的调用中完成,但也可以在对getValue的调用中完成。

// 定义Parser,可以定义全局的parser ExpressionParser parser = new SpelExpressionParser(); Inventor inventor = new Inventor(); EvaluationContext context = SimpleEvaluationContext.forReadWriteDataBinding().build(); parser.parseExpression("Name").setValue(context, inventor, "Aleksandar Seovic"); System.out.println(inventor.getName()); // Aleksandar Seovic // 或者这样赋值 String aleks = parser.parseExpression( "Name = 'Aleksandar Seovic2'").getValue(context, inventor, String.class); System.out.println(inventor.getName()); // Aleksandar Seovic2 8、获取类的类型

可以使用特殊的T运算符来指定java.lang.Class的实例(类型)。静态方法也是通过使用这个操作符来调用的。

StandardEvaluationContext使用TypeLocator来查找类型,StandardTypeLocator(可以替换)是基于对java.lang包的理解而构建的。所以java.lang中类型的T()引用不需要使用全限定名,但是其他包中的类,必须使用全限定名。

ExpressionParser parser = new SpelExpressionParser(); Class dateClass = parser.parseExpression("T(java.util.Date)").getValue(Class.class); Class stringClass = parser.parseExpression("T(String)").getValue(Class.class); boolean trueValue = parser.parseExpression( "T(java.math.RoundingMode).CEILING < T(java.math.RoundingMode).FLOOR") .getValue(Boolean.class); 9、调用类构造器

使用new运算符调用构造函数。除了基本类型(int、float等)和String之外,所有类型都应该使用完全限定的类名。

Inventor einstein = p.parseExpression( "new org.spring.samples.spel.inventor.Inventor('Albert Einstein', 'German')") .getValue(Inventor.class); //创建一个新的Inventor,并且添加到members的list中 p.parseExpression( "Members.add(new org.spring.samples.spel.inventor.Inventor( 'Albert Einstein', 'German'))").getValue(societyContext); 10、SpEL变量 (1)基本使用

可以使用#variableName语法在表达式中引用变量。通过在EvaluationContext实现上使用setVariable方法来设置变量

ExpressionParser parser = new SpelExpressionParser(); Inventor tesla = new Inventor("Nikola Tesla", "Serbian"); EvaluationContext context = SimpleEvaluationContext.forReadWriteDataBinding().build(); context.setVariable("newName", "Mike Tesla"); // 设置变量 // 获取变量newName,并将其赋值给name属性 parser.parseExpression("Name = #newName").getValue(context, tesla); System.out.println(tesla.getName()); // "Mike Tesla" (2)#this 和 #root变量

#this变量引用当前的评估对象(根据该评估对象解析非限定引用)。

#root变量总是被定义并引用根上下文对象。虽然#this可能会随着表达式的组成部分的计算而变化,但是#root总是指根。

// 创建一个Integer数组 List primes = new ArrayList(); primes.addAll(Arrays.asList(2,3,5,7,11,13,17)); // create parser and set variable 'primes' as the array of integers ExpressionParser parser = new SpelExpressionParser(); EvaluationContext context = SimpleEvaluationContext.forReadWriteDataBinding().build(); context.setVariable("primes", primes); // numbers > 10 的 list // evaluates to [11, 13, 17] List primesGreaterThanTen = (List) parser.parseExpression( "#primes.?[#this>10]").getValue(context); System.out.println(primesGreaterThanTen); 11、调用类静态方法 // 方法定义的方式 Method method = ...; EvaluationContext context = SimpleEvaluationContext.forReadOnlyDataBinding().build(); context.setVariable("myFunction", method); // 准备一个要调用的目标方法 public class StringUtils { public static String reverseString(String input) { StringBuilder backwards = new StringBuilder(input.length()); for (int i = 0; i


【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3