Spring Expression
Spring表达式语言
Spring表达式是一个支持查询和操作运行时对象de强大表达式语言,预发类似EL,提供额外的功能,函数调用和简单字符串的模板函数。别的java表达式语言还有 OGNL, MVEL,JBoss EL 等等。
SpEL不依赖于Spring,可以独立使用,当然也可以在Spring中使用。下边是使用官网的例子作为演示:
https://docs.spring.io/spring/docs/4.2.9.RELEASE/spring-framework-reference/html/expressions.html
简单的表达式
准备需要的测试类
package com.jd.spel.bean;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
/**
* @author
* @date 2018/10/16 14:33
*/
public class Inventor {
public List<Boolean> booleanList = new ArrayList<Boolean>();
public List<String> list;
private String name;
private Date brithday;
private String nationality;
private String[] inventions;
private PlaceOfBirth placeOfBirth;
public Inventor() {
this.brithday = new Date();
}
public Inventor(String name, Date brithday, String nationality) {
this.name = name;
this.brithday = brithday;
this.nationality = nationality;
}
public String getName() {
return name;
}
public Date getBrithday() {
return brithday;
}
public String getNationality() {
return nationality;
}
public String[] getInventions() {
return inventions;
}
public PlaceOfBirth getPlaceOfBirth() {
return placeOfBirth;
}
public void setInventions(String[] inventions) {
this.inventions = inventions;
}
public void setPlaceOfBirth(PlaceOfBirth placeOfBirth) {
this.placeOfBirth = placeOfBirth;
}
public void setBooleanList(List<Boolean> booleanList) {
this.booleanList = booleanList;
}
public void setList(List<String> list) {
this.list = list;
}
public void setName(String name) {
this.name = name;
}
public void setBrithday(Date brithday) {
this.brithday = brithday;
}
public void setNationality(String nationality) {
this.nationality = nationality;
}
}
package com.jd.spel.bean;
/**
*
* @date 2018/10/16 14:32
*/
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;
}
}
package com.jd.spel.bean;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
/**
*
* @date 2018/10/16 14:31
*/
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;
}
}
/**
* 该类官网例子中没有,我这边建立的,有个认识就好
*/
class Ieee {
private List<Inventor> members;
public Ieee() {
members = new ArrayList<>();
for (int i = 0; i < 4; i++) {
members.add(new Inventor("" + i, new Date(), "" + i));
}
members.get(0).setInventions(new String[]{"1212","12121"});
}
public List<Inventor> getMembers() {
return members;
}
public void setMembers(List<Inventor> members) {
this.members = members;
}
}
使用基本的表达式处理
ExpressionParser parser = new SpelExpressionParser();
Expression exp = parser.parseExpression("'Hello World'");
String message = (String) exp.getValue();
System.out.println("使用简单的Expression解析表达式 " + message);
System.out.println("使用简单的Expression解析使用concat表达式 " + message);
exp = parser.parseExpression("'Hello World'.concat('!')");
System.out.println("concat !" + (String) exp.getValue());
// invokes 'getBytes()'
exp = parser.parseExpression("'Hello World'.bytes");
byte[] bytes = (byte[]) exp.getValue();
System.out.println("bytes " + bytes);
// invokes 'getBytes().length'
exp = parser.parseExpression("'Hello World'.bytes.length");
int length = (Integer) exp.getValue();
System.out.println("bytes.length " + length);
exp = parser.parseExpression("new String('hello world').toUpperCase()");
message = exp.getValue(String.class);
System.out.println("toUpperCase " + message);
//执行后的结果-=---============
使用简单的Expression解析表达式 Hello World
使用简单的Expression解析使用concat表达式 Hello World
concat !Hello World!
bytes [B@1553973
bytes.length 11
toUpperCase HELLO WORLD
使用简单对象处理
// Create and set a calendar
GregorianCalendar c = new GregorianCalendar();
c.set(1856, 7, 9);
ExpressionParser parser = new SpelExpressionParser();
Expression exp = parser.parseExpression("name");
Inventor inventor = new Inventor("Nikola Tesla", c.getTime(), "Serbian");
//
Inventor inventor1 = new Inventor("222", c.getTime(), "Serbian");
EvaluationContext context = new StandardEvaluationContext(inventor1);
String name = (String) exp.getValue(context); //获得标准容器
System.out.println("context: Inventor.name ->" + name);
// The constructor arguments are name, birthday, and nationality.
name = (String) exp.getValue(inventor);
System.out.println("auto: Inventor.name ->" + name);
exp = parser.parseExpression("name == 'Nikola Tesla'");
boolean result = exp.getValue(context, Boolean.class); // evaluates to true
System.out.println("evaluates boolean :" + result);
//运行后的结构-========
context: Inventor.name ->222
auto: Inventor.name ->Nikola Tesla
evaluates boolean :false
类型装换
ExpressionParser parser = new SpelExpressionParser();
Inventor simple = new Inventor();
simple.booleanList.add(false);
StandardEvaluationContext simpleContext = new StandardEvaluationContext(simple);
parser.parseExpression("booleanList[0]").setValue(simpleContext, "false");
// b will be false
Boolean b = simple.booleanList.get(0);
System.out.println("Type Conversion " + b);
//运行后的结构-========
Type Conversion false
重构解析器配置
// 打开配置:
// - 引用值动态设置为null
// - 自动增加集合的大小
SpelParserConfiguration config = new SpelParserConfiguration(true, true);
ExpressionParser parser = new SpelExpressionParser(config);
Expression expression = parser.parseExpression("list[3]");
Inventor demo = new Inventor();
Object o = expression.getValue(demo);
System.out.println("ParserConfiguration " + o);
//运行结果=====================
ParserConfiguration //这里的o什么也没有输出
//设置使用立即编译模式 有三种模式,
SpelParserConfiguration config = new SpelParserConfiguration(SpelCompilerMode.IMMEDIATE,
this.getClass().getClassLoader());
SpelExpressionParser parser = new SpelExpressionParser(config);
Expression expr = parser.parseExpression("name");
Inventor message = new Inventor();
Object payload = expr.getValue(message);
System.out.println(payload); //输入位null
properties, arrays, lists, maps
这里就不写例子了。在我们的系统配置文件上下文用过。
属性引用
Inventor simple = new Inventor();
simple.setPlaceOfBirth(new PlaceOfBirth("北京"));
StandardEvaluationContext context = new StandardEvaluationContext(simple);
// evals to 2018
int year = (Integer) parser.parseExpression("Brithday.Year + 1900").getValue(context);
String city = (String) parser.parseExpression("placeOfBirth.City").getValue(context);
System.out.println("year " + year + "; city " + city);
String[] strings = new String[]{"32", "233", "3333"};
simple.setInventions(strings);
// Inventions Array
StandardEvaluationContext teslaContext = new StandardEvaluationContext(simple);
// evaluates to "Induction motor"
String invention = parser.parseExpression("inventions[2]").getValue(
teslaContext, String.class);
System.out.println("Inventions Array " + invention);
Ieee ieee = new Ieee();
// Members List
StandardEvaluationContext societyContext = new StandardEvaluationContext(ieee);
// evaluates to "Nikola Tesla"
String name = parser.parseExpression("Members[0].Name").getValue(
societyContext, String.class);
// List and Array navigation
// evaluates to "Wireless communication"
invention = parser.parseExpression("Members[0].Inventions[1]").getValue(
societyContext, String.class);
System.out.println("Members List of Members[0].Name :" + name +"; Members[0].Inventions[1] :"+invention);
//运行结果
year 2018; city 北京
Inventions Array 3333
Members List of Members[0].Name :0; Members[0].Inventions[1] :12121
源码分析
入口代码
public class SpelExpressionParser extends TemplateAwareExpressionParser {
private final SpelParserConfiguration configuration;
/**
* Create a parser with default settings.
*/
public SpelExpressionParser() {
this.configuration = new SpelParserConfiguration();
}
/**
* Create a parser with the specified configuration.
* @param configuration custom configuration options
*/
public SpelExpressionParser(SpelParserConfiguration configuration) {
Assert.notNull(configuration, "SpelParserConfiguration must not be null");
this.configuration = configuration;
}
public SpelExpression parseRaw(String expressionString) throws ParseException {
return doParseExpression(expressionString, null);
}
@Override
protected SpelExpression doParseExpression(String expressionString, ParserContext context) throws ParseException {
//这里主要是doParseExpression执行,可以看见主要实现在nternalSpelExpressionParser中
return new InternalSpelExpressionParser(this.configuration).doParseExpression(expressionString, context);
}
}
本文深入讲解Spring表达式语言(SpEL),包括基本表达式的使用、对象处理、类型转换、解析器配置及属性引用等核心功能。通过实例演示如何在Spring环境中有效利用SpEL进行动态属性值的获取和设置。
1086

被折叠的 条评论
为什么被折叠?



