Spring中SpEL表達(dá)式的使用全解
一、概述
1、什么是SpEL
SpEL(Spring Expression Language)是Spring框架中用于表達(dá)式語言的一種方式。它類似于其他編程語言中的表達(dá)式語言,用于在運行時計算值或執(zhí)行特定任務(wù)。
SpEL提供了一種簡單且強大的方式來訪問和操作對象的屬性、調(diào)用對象的方法,以及實現(xiàn)運算、條件判斷等操作。它可以被用于XML和注解配置中,可以用于許多Spring框架中的特性,如依賴注入、AOP、配置文件等。
SpEL表達(dá)式可以在字符串中進(jìn)行定義,使用特殊的語法和符號來表示特定的操作。例如,可以使用${expression}來表示一個SpEL表達(dá)式,其中expression是具體的SpEL語句。
SpEL支持各種操作和函數(shù),包括算術(shù)運算、邏輯運算、條件判斷、正則表達(dá)式匹配、集合操作等。它還支持訪問上下文中的變量和參數(shù),以及調(diào)用對象的方法。
2、SpEL能做什么
SpEL表達(dá)式具有廣泛的功能,以下是一些SpEL表達(dá)式可以做的事情:
- 訪問對象屬性:SpEL表達(dá)式可以通過對象引用來訪問對象的屬性,例如
${object.property}
。 - 調(diào)用方法:SpEL表達(dá)式可以調(diào)用對象的方法,例如
${object.method()}
。 - 進(jìn)行算術(shù)運算:SpEL表達(dá)式支持各種算術(shù)運算符,如加法、減法、乘法和除法。
- 進(jìn)行邏輯運算:SpEL表達(dá)式支持邏輯運算符,如與、或、非等。
- 進(jìn)行條件判斷:SpEL表達(dá)式可以進(jìn)行條件判斷,例如通過if語句判斷條件,并執(zhí)行相應(yīng)的操作。
- 訪問集合元素和屬性:SpEL表達(dá)式可以通過索引或鍵來訪問集合中的元素或?qū)ο蟮膶傩浴?/li>
- 執(zhí)行正則表達(dá)式匹配:SpEL表達(dá)式可以執(zhí)行正則表達(dá)式匹配,并返回匹配結(jié)果。
- 訪問上下文變量和參數(shù):SpEL表達(dá)式可以訪問上下文中的變量和方法參數(shù)。
- 進(jìn)行類型轉(zhuǎn)換:SpEL表達(dá)式可以進(jìn)行類型轉(zhuǎn)換操作,將一個對象轉(zhuǎn)換為另一種類型。
- 支持特殊操作符:SpEL表達(dá)式支持一些特殊的操作符,如Elvis操作符(
?:
)、安全導(dǎo)航操作符(?.
)等。
總的來說,SpEL表達(dá)式可以用于在運行時計算值、執(zhí)行任務(wù)和操作對象,提供了靈活且強大的表達(dá)能力,廣泛應(yīng)用于Spring框架中的各種功能和配置中。
二、SpEL表達(dá)式使用
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<Inventor> members = new ArrayList<Inventor>(); 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、文字表達(dá)式
支持的文字表達(dá)式類型有字符串、數(shù)值(int、real、hex)、布爾和null。字符串由單引號
分隔。若要將單引號本身放在字符串中,請使用兩個單引號字符。
通常來說,不會單純的定義一個簡單的文字表達(dá)式,而是通過方法調(diào)用等等復(fù)雜的操作,來完成一個功能:
// 定義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、屬性, 數(shù)組, List, Map,和 索引
(1)屬性操作
注意!屬性名的第一個字母不區(qū)分大小寫
。
// 定義Parser,可以定義全局的parser ExpressionParser parser = new SpelExpressionParser(); // 注意!屬性名的第一個字母不區(qū)分大小寫。 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)數(shù)組和List
數(shù)組和List的內(nèi)容是通過使用方括號符號獲得的。
// 定義Parser,可以定義全局的parser ExpressionParser parser = new SpelExpressionParser(); EvaluationContext context = SimpleEvaluationContext.forReadOnlyDataBinding().build(); // 省略數(shù)據(jù)初始化 // 取出tesla對象的inventions 第四個數(shù)據(jù) 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、內(nèi)嵌List
可以使用{}
符號在表達(dá)式中直接表示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、內(nèi)嵌Map
使用{key:value}
符號在表達(dá)式中表示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可以嵌套使用,互相結(jié)合。 // 嵌套:[{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、構(gòu)建數(shù)組
多維數(shù)組不提供初始化方式。
// 定義Parser,可以定義全局的parser ExpressionParser parser = new SpelExpressionParser(); EvaluationContext context = SimpleEvaluationContext.forReadOnlyDataBinding().build(); int[] numbers1 = (int[]) parser.parseExpression("new int[4]").getValue(context); // 數(shù)組并初始化 int[] numbers2 = (int[]) parser.parseExpression("new int[]{1,2,3}").getValue(context); // 多維數(shù)組 int[][] numbers3 = (int[][]) parser.parseExpression("new int[4][5]").getValue(context);
6、調(diào)用類的方法
ExpressionParser parser = new SpelExpressionParser(); // 調(diào)用substring方法 String bc = parser.parseExpression("'abc'.substring(1, 3)").getValue(String.class); // 調(diào)用societyContext中對象的isMember方法,并傳值。 StandardEvaluationContext societyContext = new StandardEvaluationContext(society); boolean isMember = parser.parseExpression("isMember('Mihajlo Pupin')").getValue( societyContext, Boolean.class);
7、SpEL操作符
(1)標(biāo)準(zhǔn)運算符
使用標(biāo)準(zhǔn)運算符表示法支持關(guān)系運算符(等于、不等于、小于、小于或等于、大于和大于或等于)。
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 和 正則表達(dá)式的匹配操作符
使用基本類型時要小心,因為它們會立即被裝箱為包裝器類型,所以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)操作符的英文等價標(biāo)識
每個符號操作符也可以被指定為純字母的等價物
。這避免了所使用的符號對于嵌入表達(dá)式的文檔類型具有特殊含義的問題(例如在XML文檔中)。所有文本操作符都不區(qū)分大小寫
。對應(yīng)的文本是:
lt (<)
gt (>)
le (<=)
ge (>=)
eq (==)
ne (!=)
div (/)
mod (%)
not (!)
(4)邏輯運算符
SpEL支持以下邏輯運算符:and、or、not
// 結(jié)果: false boolean falseValue = parser.parseExpression("true and false").getValue(Boolean.class); // 調(diào)用方法并根據(jù)方法返回值判斷 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); // 調(diào)用方法并根據(jù)方法返回值判斷 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)數(shù)學(xué)運算符
可以對數(shù)字和字符串使用加法運算符
。只能對數(shù)字使用減法、乘法和除法運算符
。
也可以使用模數(shù)(%)和指數(shù)冪(^)
運算符。
強制執(zhí)行標(biāo)準(zhǔn)運算符優(yōu)先級。
// 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)賦值運算符
若要給對象設(shè)置屬性,請使用賦值運算符(=)
。這通常在對setValue的調(diào)用中完成,但也可以在對getValue的調(diào)用中完成。
// 定義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
的實例(類型)。靜態(tài)方法也是通過使用這個操作符來調(diào)用的。
StandardEvaluationContext
使用TypeLocator
來查找類型,StandardTypeLocator(
可以替換)是基于對java.lang
包的理解而構(gòu)建的。所以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、調(diào)用類構(gòu)造器
使用new
運算符調(diào)用構(gòu)造函數(shù)。除了基本類型(int、float等
)和String
之外,所有類型都應(yīng)該使用完全限定的類名。
Inventor einstein = p.parseExpression( "new org.spring.samples.spel.inventor.Inventor('Albert Einstein', 'German')") .getValue(Inventor.class); //創(chuàng)建一個新的Inventor,并且添加到members的list中 p.parseExpression( "Members.add(new org.spring.samples.spel.inventor.Inventor( 'Albert Einstein', 'German'))").getValue(societyContext);
10、SpEL變量
(1)基本使用
可以使用#variableName
語法在表達(dá)式中引用變量。通過在EvaluationContext
實現(xiàn)上使用setVariable
方法來設(shè)置變量
ExpressionParser parser = new SpelExpressionParser(); Inventor tesla = new Inventor("Nikola Tesla", "Serbian"); EvaluationContext context = SimpleEvaluationContext.forReadWriteDataBinding().build(); context.setVariable("newName", "Mike Tesla"); // 設(shè)置變量 // 獲取變量newName,并將其賦值給name屬性 parser.parseExpression("Name = #newName").getValue(context, tesla); System.out.println(tesla.getName()); // "Mike Tesla"
(2)#this 和 #root變量
#this變量引用當(dāng)前的評估對象(根據(jù)該評估對象解析非限定引用)。
#root變量總是被定義并引用根上下文對象。雖然#this可能會隨著表達(dá)式的組成部分的計算而變化,但是#root總是指根。
// 創(chuàng)建一個Integer數(shù)組 List<Integer> primes = new ArrayList<Integer>(); 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<Integer> primesGreaterThanTen = (List<Integer>) parser.parseExpression( "#primes.?[#this>10]").getValue(context); System.out.println(primesGreaterThanTen);
11、調(diào)用類靜態(tài)方法
// 方法定義的方式 Method method = ...; EvaluationContext context = SimpleEvaluationContext.forReadOnlyDataBinding().build(); context.setVariable("myFunction", method);
// 準(zhǔn)備一個要調(diào)用的目標(biāo)方法 public class StringUtils { public static String reverseString(String input) { StringBuilder backwards = new StringBuilder(input.length()); for (int i = 0; i < input.length(); i++) { backwards.append(input.charAt(input.length() - 1 - i)); } return backwards.toString(); } } // 調(diào)用目標(biāo)靜態(tài)方法 public static void main(String[] args) throws NoSuchMethodException { ExpressionParser parser = new SpelExpressionParser(); EvaluationContext context = SimpleEvaluationContext.forReadOnlyDataBinding().build(); // 獲取要調(diào)用的方法 context.setVariable("reverseString", StringUtils.class.getDeclaredMethod("reverseString", String.class)); // 調(diào)用 String helloWorldReversed = parser.parseExpression( "#reverseString('hello')").getValue(context, String.class); }
12、Bean引用
如果已經(jīng)用bean解析器配置了評估上下文,則可以使用@
符號從表達(dá)式中查找bean。
ExpressionParser parser = new SpelExpressionParser(); StandardEvaluationContext context = new StandardEvaluationContext(); context.setBeanResolver(new MyBeanResolver()); // 將調(diào)用MyBeanResolver 的 resolve(context,"something") Object bean = parser.parseExpression("@something").getValue(context);
// 注意!MyBeanResolver 可以使用系統(tǒng)自帶的BeanFactoryResolver,寫成: context.setBeanResolver(new BeanFactoryResolver(applicationContext)); // BeanFactoryResolver的resolve方法,就是通過Bean的名稱來獲取Bean: @Override public Object resolve(EvaluationContext context, String beanName) throws AccessException { try { return this.beanFactory.getBean(beanName); } catch (BeansException ex) { throw new AccessException("Could not resolve bean reference against BeanFactory", ex); } }
要訪問工廠bean本身,應(yīng)該在bean名稱前加上&
符號:
ExpressionParser parser = new SpelExpressionParser(); StandardEvaluationContext context = new StandardEvaluationContext(); context.setBeanResolver(new MyBeanResolver()); // 將調(diào)用MyBeanResolver 的 resolve(context,"something") Object bean = parser.parseExpression("&foo").getValue(context);
13、三元運算符(If-Then-Else)
// 使用示例 String falseString = parser.parseExpression( "false ? 'trueExp' : 'falseExp'").getValue(String.class);
// name屬性設(shè)置值 parser.parseExpression("Name").setValue(societyContext, "IEEE"); // 設(shè)置變量 societyContext.setVariable("queryName", "Nikola Tesla"); // 三元運算符 expression = "isMember(#queryName)? #queryName + ' is a member of the ' " + "+ Name + ' Society' : #queryName + ' is not a member of the ' + Name + ' Society'"; String queryResultString = parser.parseExpression(expression) .getValue(societyContext, String.class); // queryResultString = "Nikola Tesla is a member of the IEEE Society"
14、Elvis操作符
Elvis運算符是三元運算符語法的縮寫,用于Groovy語言中。使用三元運算符語法時,通常需要將一個變量重復(fù)兩次,如下例所示:
String name = "Elvis Presley"; String displayName = (name != null ? name : "Unknown");
可以使用Elvis運算符(因與Elvis的發(fā)型相似而得名)優(yōu)化。以下示例顯示了如何使用Elvis運算符:
ExpressionParser parser = new SpelExpressionParser(); String name = parser.parseExpression("name?:'Unknown'").getValue(String.class); System.out.println(name); // 'Unknown'
更復(fù)雜的實例:
ExpressionParser parser = new SpelExpressionParser(); EvaluationContext context = SimpleEvaluationContext.forReadOnlyDataBinding().build(); Inventor tesla = new Inventor("Nikola Tesla", "Serbian"); String name = parser.parseExpression("Name?:'Elvis Presley'").getValue(context, tesla, String.class); System.out.println(name); // Nikola Tesla tesla.setName(null); name = parser.parseExpression("Name?:'Elvis Presley'").getValue(context, tesla, String.class); System.out.println(name); // Elvis Presley
15、安全導(dǎo)航操作員
安全導(dǎo)航操作符用于避免NullPointerException
,來自Groovy語言。通常,當(dāng)引用一個對象時,可能需要在訪問該對象的方法或?qū)傩灾膀炞C它不為null。為了避免這種情況,安全導(dǎo)航運算符返回null,而不是引發(fā)異常。以下示例顯示了如何使用安全導(dǎo)航運算符:
ExpressionParser parser = new SpelExpressionParser(); EvaluationContext context = SimpleEvaluationContext.forReadOnlyDataBinding().build(); Inventor tesla = new Inventor("Nikola Tesla", "Serbian"); tesla.setPlaceOfBirth(new PlaceOfBirth("Smiljan")); String city = parser.parseExpression("PlaceOfBirth?.City").getValue(context, tesla, String.class); System.out.println(city); // Smiljan tesla.setPlaceOfBirth(null); city = parser.parseExpression("PlaceOfBirth?.City").getValue(context, tesla, String.class); System.out.println(city); // null - does not throw NullPointerException!!!
16、集合選擇
// 語法.?[selectionExpression] List<Inventor> list = (List<Inventor>) parser.parseExpression( "Members.?[Nationality == 'Serbian']").getValue(societyContext); // 返回value小于27的值 Map newMap = parser.parseExpression("map.?[value<27]").getValue();
除了返回所有選定的元素之外,還可以只檢索第一個或最后一個值。要獲得匹配選擇的第一個條目,語法是。.^[selectionExpression]
.要獲得最后一個匹配的選擇,語法是。.$[選擇表達(dá)式]
。
17、集合投影
// 語法:.![projectionExpression] // returns ['Smiljan', 'Idvor' ] List placesOfBirth = (List)parser.parseExpression("Members.![placeOfBirth.city]");
18、表達(dá)式模板
// 通常使用#{}作為模板,與字符串拼接起來 String randomPhrase = parser.parseExpression( "random number is #{T(java.lang.Math).random()}", new TemplateParserContext()).getValue(String.class); // evaluates to "random number is 0.7038186818312008"
// TemplateParserContext 的定義 public class TemplateParserContext implements ParserContext { public String getExpressionPrefix() { return "#{"; } public String getExpressionSuffix() { return "}"; } public boolean isTemplate() { return true; } }
參考資料
到此這篇關(guān)于Spring中SpEL表達(dá)式的使用全解的文章就介紹到這了,更多相關(guān)Spring SpEL表達(dá)式內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
- Spring中@Value使用詳解及SPEL表達(dá)式
- 詳解Spring中Spel表達(dá)式和el表達(dá)式的區(qū)別
- SpringDataElasticsearch與SpEL表達(dá)式實現(xiàn)ES動態(tài)索引
- Spring AOP如何在注解上使用SPEL表達(dá)式注入對象
- spring之SpEL表達(dá)式詳解
- 使用Springboot自定義注解,支持SPEL表達(dá)式
- 基于spring?@Cacheable?注解的spel表達(dá)式解析執(zhí)行邏輯
- Spring?Cache抽象-使用SpEL表達(dá)式解析
- Spring實戰(zhàn)之Bean定義中的SpEL表達(dá)式語言支持操作示例
- Spring組件開發(fā)模式支持SPEL表達(dá)式
- Spring spel表達(dá)式使用方法示例
相關(guān)文章
Springboot WebFlux集成Spring Security實現(xiàn)JWT認(rèn)證的示例
這篇文章主要介紹了Springboot WebFlux集成Spring Security實現(xiàn)JWT認(rèn)證的示例,幫助大家更好的理解和學(xué)習(xí)使用springboot框架,感興趣的朋友可以了解下2021-04-04java mybatis框架實現(xiàn)多表關(guān)系查詢功能
這篇文章主要介紹了java mybatis框架實現(xiàn)多表關(guān)系查詢,基于Maven框架的整體設(shè)計 —— 一多一的關(guān)系,文中通過實例代碼給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下2021-10-10JAVA生產(chǎn)者消費者(線程同步)代碼學(xué)習(xí)示例
這篇文章主要介紹了JAVA線程同步的代碼學(xué)習(xí)示例,大家參考使用吧2013-11-11MyBatisPlus使用${ew.customSqlSegment}別名問題解決
在使用MyBatisPlus進(jìn)行連表查詢時,可能遇到因${ew.customSqlSegment}無法加別名的問題,本文就來介紹一下如何解決,感興趣的可以了解一下2024-10-10Java通過反射機制動態(tài)設(shè)置對象屬性值的方法
下面小編就為大家?guī)硪黄狫ava通過反射機制動態(tài)設(shè)置對象屬性值的方法。小編覺得挺不錯的,現(xiàn)在就分享給大家,也給大家做個參考。一起跟隨小編過來看看吧2016-07-07