欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

Spring中SpEL表達(dá)式的使用全解

 更新時間:2024年04月09日 09:42:11   作者:禿了也弱了。  
SpEL是Spring框架中用于表達(dá)式語言的一種方式,本文主要介紹了Spring中SpEL表達(dá)式的使用全解,文中通過示例代碼介紹的非常詳細(xì),需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧

一、概述

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;
    }
}

參考資料

https://docs.spring.io/spring-framework/docs/5.1.6.RELEASE/spring-framework-reference/core.html#expressions

到此這篇關(guān)于Spring中SpEL表達(dá)式的使用全解的文章就介紹到這了,更多相關(guān)Spring SpEL表達(dá)式內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • JSONObject如何轉(zhuǎn)為實體類對象

    JSONObject如何轉(zhuǎn)為實體類對象

    介紹了JSONObject轉(zhuǎn)為實體類對象的三種方法:JSONObject中的toJavaObject方法和getObject方法支持深轉(zhuǎn)換,而JSON中的parseObject方法只能轉(zhuǎn)換一層對象,此外,還補充說明了在對JSON轉(zhuǎn)為實體類對象時,無論JSON中的數(shù)據(jù)字段是否多于或少于實體類中字段,轉(zhuǎn)化都不會報錯
    2024-11-11
  • 淺談一下Java中的ReentrantLock

    淺談一下Java中的ReentrantLock

    這篇文章主要介紹了淺談一下Java中的ReentrantLock,這個類是JUC工具包中對線程安全問題提供的一種解決方案,它主要是用來給對象上鎖,保證同一時間這能有一個線程在訪問當(dāng)前對象,需要的朋友可以參考下
    2023-09-09
  • 一文了解Java動態(tài)代理的原理及實現(xiàn)

    一文了解Java動態(tài)代理的原理及實現(xiàn)

    動態(tài)代理指的是,代理類和目標(biāo)類的關(guān)系在程序運行的時候確定的,客戶通過代理類來調(diào)用目標(biāo)對象的方法,是在程序運行時根據(jù)需要動態(tài)的創(chuàng)建目標(biāo)類的代理對象。本文將通過案例詳細(xì)講解一下Java動態(tài)代理的原理及實現(xiàn),需要的可以參考一下
    2022-07-07
  • Springboot WebFlux集成Spring Security實現(xiàn)JWT認(rèn)證的示例

    Springboot WebFlux集成Spring Security實現(xiàn)JWT認(rèn)證的示例

    這篇文章主要介紹了Springboot WebFlux集成Spring Security實現(xiàn)JWT認(rèn)證的示例,幫助大家更好的理解和學(xué)習(xí)使用springboot框架,感興趣的朋友可以了解下
    2021-04-04
  • java mybatis框架實現(xiàn)多表關(guān)系查詢功能

    java mybatis框架實現(xiàn)多表關(guān)系查詢功能

    這篇文章主要介紹了java mybatis框架實現(xiàn)多表關(guān)系查詢,基于Maven框架的整體設(shè)計 —— 一多一的關(guān)系,文中通過實例代碼給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2021-10-10
  • JAVA生產(chǎn)者消費者(線程同步)代碼學(xué)習(xí)示例

    JAVA生產(chǎn)者消費者(線程同步)代碼學(xué)習(xí)示例

    這篇文章主要介紹了JAVA線程同步的代碼學(xué)習(xí)示例,大家參考使用吧
    2013-11-11
  • MyBatisPlus使用${ew.customSqlSegment}別名問題解決

    MyBatisPlus使用${ew.customSqlSegment}別名問題解決

    在使用MyBatisPlus進(jìn)行連表查詢時,可能遇到因${ew.customSqlSegment}無法加別名的問題,本文就來介紹一下如何解決,感興趣的可以了解一下
    2024-10-10
  • Mybatis打印SQL語句的幾種常用方式

    Mybatis打印SQL語句的幾種常用方式

    當(dāng)我們動態(tài)sql拼接的塊很多的時候,我們要想從*mapper.xml中直接找出完整的sql就會非常的難,這個時候經(jīng)常會需要把組合之后的完整SQL語句打印出來,對調(diào)試非常有幫助的,所以本文小編給大家介紹了幾種Mybatis打印SQL語句的常用方式,需要的朋友可以參考下
    2023-11-11
  • MyBatis?Xml映射文件之字符串替換方式

    MyBatis?Xml映射文件之字符串替換方式

    這篇文章主要介紹了MyBatis?Xml映射文件之字符串替換方式,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2021-11-11
  • Java通過反射機制動態(tài)設(shè)置對象屬性值的方法

    Java通過反射機制動態(tài)設(shè)置對象屬性值的方法

    下面小編就為大家?guī)硪黄狫ava通過反射機制動態(tài)設(shè)置對象屬性值的方法。小編覺得挺不錯的,現(xiàn)在就分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2016-07-07

最新評論