目录
目录
0,基本信息
1, 官网地址:
SpringEL 官网地址
这一块是关于SpringEL的内容
2,引入jar包:
搜索: spring-expression 不是搜索 SpringEL
会看到:
点击进去,会看到各种版本:
选择一个版本,点击进去
里面会有各种项目的引入方式,比如常见的Maven和Gradle
// Maven:
<!-- https://mvnrepository.com/artifact/org.springframework/spring-expression -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-expression</artifactId>
<version>5.2.5.RELEASE</version>
</dependency>
// Gradle :
// https://mvnrepository.com/artifact/org.springframework/spring-expression
compile group: 'org.springframework', name: 'spring-expression', version: '5.2.5.RELEASE'
引入jar后,就可以一边学,一边操作了。
1,概念:
什么是SpringEL?
Spring3中引入了Spring表达式语言—SpringEL,SpEL是一种强大的描述语言,简洁的装配Bean的方式,可以通过运行期间执行的表达式将值装配到属性或构造函数当中,更可以调用JDK中提供的静态常量,获取外部Properties文件中的的配置。支在在运行期间对象图里面的数据查询和数据操作。语法和标准的EL一样,而且支持一些额外的功能特性,最显著的就是方法调用以及基本字符串模板函数功能。
基本语法结构:(重点)
#{ } 标记会提示Spring 这个标记里的内容是SpEL表达式。 当然,这个可以通过Expression templating功能扩展做改造
#{rootBean.nestBean.propertiy} “.” 操作符表示属性或方法引用,支持层次调用
#{aList[0] } 数组和列表使用方括号获得内容
#{aMap[key] } maps使用方括号获得内容
#{rootBean?.propertiy} 此处"?"是安全导航运算符器,避免空指针异常
#{condition ? trueValue : falseValue} 三元运算符(IF-THEN-ELSE)
#{valueA?:defaultValue} ELvis操作符,当valueA为空时赋值defaultValue
常见的应用:
1,数值运算,比如对四则运算的处理
计算24小时有多少秒:
EvaluationContext context = new StandardEvaluationContext(); // 表达式的上下文
ExpressionParser parser = new SpelExpressionParser();
Long seconds = parser.parseExpression("24*60*60").getValue(context, Long.class);
System.out.println("seconds " + seconds);
2,字符串替换赋值
比如es的查询串:
"{\"size\":#{#size},\"from\":#{#from},\"query\":{\"bool\":"
+ "{\"must\":[{\"range\":{\"#{#timeStamp}\":{\"gte\":\"#{#startDate}\","
+ "\"lte\":\"#{#endDate}\",\"format\":\"yyyy-MM-dd HH:mm:ss\","
+ "\"time_zone\":\"+00:00\"}}}#{#wildCard}]#{#filter}}}}";
替换里面#{# }的内容,具体例子代码在下一篇应用中展示
2,各种类型:
// 先声明一个通用的:
private static final ExpressionParser PARSER = new SpelExpressionParser();
// 一个分隔函数:
public static void addPrintGap(String method){
System.out.println();
System.out.println("====================== "+ method +" ======================");
}
0,引用的实体类:
类Invertor
public class Inventor {
private String name;
private Date birthday;
private PlaceOfBirth birthPlace;
private String nationality;
private String[] inventions;
public Inventor() {
}
public Inventor(String name, String nationality) {
this.name = name;
this.nationality = nationality;
}
public Inventor(String name, Date birthday, String nationality) {
this.name = name;
this.birthday = birthday;
this.nationality = nationality;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String[] getInventions() {
return inventions;
}
public void setInventions(String[] inventions) {
this.inventions = inventions;
}
public Date getBirthday() {
return birthday;
}
public void setBirthday(Date birthday) {
this.birthday = birthday;
}
public PlaceOfBirth getBirthPlace() {
return birthPlace;
}
public void setBirthPlace(PlaceOfBirth birthPlace) {
this.birthPlace = birthPlace;
}
public String getNationality() {
return nationality;
}
public void setNationality(String nationality) {
this.nationality = nationality;
}
@Override
public String toString() {
return "Inventor{" + "name='" + name + '\'' + ", birthday=" + birthday + ", nationality='" + nationality + '\''
+ '}';
}
}
PlaceOfBirth类
public class PlaceOfBirth {
private String city;
private String country;
public PlaceOfBirth(String city) {
this.city = city;
}
public PlaceOfBirth(String city, String country) {
this.city = city;
this.country = country;
}
public String getCity() {
return city;
}
public void setCity(String city) {
this.city = city;
}
public String getCountry() {
return country;
}
public void setCountry(String country) {
this.country = country;
}
}
Society 类
public class Society {
private List<Inventor> member = new ArrayList<>();
private Map<String, Object> mguest = new HashMap<>();
private Map officer;
public List<Inventor> getMember() {
return member;
}
public void setMember(List<Inventor> member) {
this.member = member;
}
public Map<String, Object> getMguest() {
return mguest;
}
public void setMguest(Map<String, Object> mguest) {
this.mguest = mguest;
}
}
1,基本类型:字符:
public static void testBase() {
// 字符串这边,跟用字符的使用一致,concat,length等
// message = exp.getValue(String.class);
// message = (String) exp.getValue();
// 两个方式中,我觉得用 cast to 的方式会方便些,有些时候不好指定
addPrintGap("testBase");
Expression exp = PARSER.parseExpression("'Hello World'");
String message = (String) exp.getValue();
System.out.println("message:" + message);
exp = PARSER.parseExpression("'Hello World'.concat('!')");
message = (String) exp.getValue();
System.out.println("message concat:" + message);
// 调用String这个javaBean的'getBytes()'
exp = PARSER.parseExpression("'Hello World'.bytes");
byte[] bytes = (byte[]) exp.getValue();
System.out.println("字节内容:" + Arrays.toString(bytes));
// 嵌套的bean实例方法调用,通过'.'运算符
exp = PARSER.parseExpression("'Hello World'.bytes.length");
int len = (int) exp.getValue();
System.out.println("字节长度:" + len);
exp = PARSER.parseExpression("'Hello World'.toUpperCase()");
message = exp.getValue(String.class);
System.out.println("message toUpperCase:" + message);
}
2,对象属性
public static void testObjectProperty(){
// 对象property访问
GregorianCalendar c = new GregorianCalendar();
c.set(2020, 10, 1);
// Inventor的构造函数参数分别是:name, birthday, and nationality
Inventor tesla = new Inventor("Nokola Testla", c.getTime(), "china");
// 解析对应的属性
Expression exp = PARSER.parseExpression("nationality");
// 对 对象进行 变形处理
EvaluationContext context = new StandardEvaluationContext(tesla);
// 获取到对应的值, exp里面的内容
String nationality = (String) exp.getValue(context);
System.out.println("invertor nationality: "+nationality);
System.out.println("invertor name: " + PARSER.parseExpression("name").getValue(context));
System.out.println("invertor birthday: " + PARSER.parseExpression("birthday").getValue(context));
// 对象实例的成员进行操作。 evals to 1856, 注意纪年中,起点是从1900开始
int year = (int) PARSER.parseExpression("birthday.Year+1900").getValue(context);
tesla.setBirthPlace(new PlaceOfBirth("BeJing city", "China"));
String city = PARSER.parseExpression("birthPlace.city").getValue(context, String.class);
System.out.println("year: " + year + ", city: " + city);
//属性中的: array, list操作
// 先测试验证array
tesla.setInventions(new String[]{"交流点", "交流电发电机", "交流电变压器", "变形记里面的缩小器"});
EvaluationContext arrContext = new StandardEvaluationContext(tesla);
String invention = PARSER.parseExpression("inventions[3]").getValue(arrContext, String.class);
String invention2 = (String) PARSER.parseExpression("inventions[2]").getValue(arrContext);
System.out.println("Array index 3: " + invention);
System.out.println("Array index 2: " + invention2);
// list 测试验证
Society society = new Society();
society.getMember().add(tesla);
StandardEvaluationContext societyContext = new StandardEvaluationContext(society);
// evaluates to "Nikola Tesla"
String mName = PARSER.parseExpression("member[0].Name").getValue(societyContext, String.class);
String nationalitys = PARSER.parseExpression("member[0].nationality").getValue(societyContext, String.class);
System.out.println("mName: " + mName + " " + ", nationality "+nationalitys);
String mInvention = PARSER.parseExpression("Member[0].Inventions[1]").getValue(societyContext, String.class);
String mInvention2 = PARSER.parseExpression("member[0].inventions[0]").getValue(societyContext, String.class);
System.out.println("mInvention: " + mInvention );
System.out.println("mInvention2: " + mInvention2);
}
3,map类型
public static void testMap() {
addPrintGap("testMap");
//e. Map的操作
//首先构建数据环境
GregorianCalendar cm = new GregorianCalendar();
cm.set(1806, 7, 9);
Inventor idv = new Inventor("Idovr", cm.getTime(), "china, haha");
Society soc = new Society();
idv.setBirthPlace(new PlaceOfBirth("武汉", "中国"));
EvaluationContext socCtxt = new StandardEvaluationContext(soc);
Inventor pupin = PARSER.parseExpression("").getValue(socCtxt, Inventor.class);
String mCity = PARSER.parseExpression("Officers['president']").getValue(socCtxt, String.class);
System.out.println("Map case 1: " + mCity);
Expression mExp = PARSER.parseExpression("");
mExp.setValue(soc, "Croatia");
String country = mExp.getValue(socCtxt, String.class);
System.out.println("Map case 2: " + country);
}
4,集合类型
// Inline lists
public static void testInlineList() {
addPrintGap("testInlineList");
List<String> numbers = (List<String>) PARSER.parseExpression("{1,2,3,4}").getValue();
System.out.println("单独列表:" + numbers.toString());
List listOfLists = (List) PARSER.parseExpression("{{'a','b'},{'x','y'}}").getValue();
System.out.println("二维列表:" + listOfLists.toString());
}
5,数组类型:
public static void testArray() {
addPrintGap("testArray");
int[] numbers1 = (int[]) PARSER.parseExpression("new int[4]").getValue();
for (int it : numbers1) {
System.out.println("numbers1 element: " + it);
}
// Array with initializer
int[] numbers2 = (int[]) PARSER.parseExpression("new int[]{1,2,3}").getValue();
for (int it : numbers2) {
System.out.println("numbers2 element: " + it);
}
// Multi dimensional array
int[][] numbers3 = (int[][]) PARSER.parseExpression("new int[4][5]").getValue();
for (int it[] : numbers3) {
System.out.println("numbers3 dim 2 size: " + it.length);
}
}
6,运算符
public static void testRelationOperators() {
addPrintGap("testRelationOperators");
// evaluates to true
boolean trueValue1 = PARSER.parseExpression("2 == 2").getValue(Boolean.class);
System.out.println("2 == 2: " + trueValue1);
// evaluates to false
boolean falseValue = PARSER.parseExpression("2 < -5.0").getValue(Boolean.class);
System.out.println("2 < -5.0: " + trueValue1);
// evaluates to true
boolean trueValue2 = PARSER.parseExpression("'black' < 'block'").getValue(Boolean.class);
System.out.println("'black' < 'block': " + trueValue2);
//任何数都比null大
boolean nullTrue = PARSER.parseExpression("0 > null").getValue(Boolean.class);
System.out.println("0 > null : " + nullTrue);
boolean nullFalse = PARSER.parseExpression("-1 < null").getValue(Boolean.class);
System.out.println("-1 < null: " + nullFalse);
// evaluates to false
boolean instanceofValue = PARSER.parseExpression("'xyz' instanceof T(int)").getValue(Boolean.class);
System.out.println("'xyz' instanceof T(int): " + instanceofValue);
// evaluates to true
boolean matchTrueValue = PARSER.parseExpression("'5.00' matches '^\\d+(\\.\\d{2})?$'").getValue(Boolean.class);
System.out.println("'5.00' matches '^\\d+(\\.\\d{2})?$': " + matchTrueValue);
//evaluates to false
boolean matchFalseValue = PARSER.parseExpression("'5.0067' matches '^\\d+(\\.\\d{2})?$'")
.getValue(Boolean.class);
System.out.println("'5.0067' matches '^\\d+(\\.\\d{2})?$': " + matchFalseValue);
// 注意:每一种符号化的运算符,都有一个对应的字母符形式的符号,主要是考虑到在某些场合可能出现转义(XML文档),对应关系如下(不区分大小写):
// lt ('<'), gt ('>'), le ('<='), ge ('>='), eq ('=='), ne ('!='), div ('/'), mod ('%'), not ('!').
//逻辑运算,支持and,or,not以及对应的组合
// -- AND -- evaluates to false
boolean andFalseValue = PARSER.parseExpression("true and false").getValue(Boolean.class);
System.out.println("true and false: " + andFalseValue);
// -- OR -- evaluates to true
boolean orTrueValue = PARSER.parseExpression("true or false").getValue(Boolean.class);
System.out.println("true or false: " + orTrueValue);
// -- NOT -- evaluates to false
boolean notFalseValue = PARSER.parseExpression("!true").getValue(Boolean.class);
System.out.println("!true: " + notFalseValue);
//算术运算,支持 +, -, *, /, mod
// Addition
int two = PARSER.parseExpression("1 + 1").getValue(Integer.class);
System.out.println("1 + 1: " + two);
String testString = PARSER.parseExpression("'test' + ' ' + 'string'").getValue(String.class);
System.out.println("'test' + ' ' + 'string': " + testString);
// Subtraction
int four = PARSER.parseExpression("1 - -3").getValue(Integer.class);
System.out.println("1 - -3: " + four);
}
7,对象赋值
/**
* 给一个javaBean对象赋值,通常都是采用setValue方法,当然,也可以通过getValue的方式实现同样的功能。
*/
public static void testAssignment() {
addPrintGap("testAssignment");
Inventor inventor = new Inventor();
StandardEvaluationContext inventorContext = new StandardEvaluationContext(inventor);
PARSER.parseExpression("name").setValue(inventorContext, "Alexander yan");
System.out.println("assignment <> inventor'name is: " + inventor.getName());
// alternatively
String aleks = PARSER.parseExpression("name = 'Alexmandar lang'").getValue(inventorContext, String.class);
System.out.println("assignment <> inventor'name is: " + aleks + " " + inventor.getName());
}
8,类型:
/**
* 特殊的T运算符可以用来指定一个java.lang.Class类的实例,即Class的实例。另外,静态方法,也可以用T运算符指定。
* T()可以用来指定java.lang包下面的类型,不必要全路径指明,但是,其他路径下的类型,必须全路径指明。
*/
public static void testClassExpression() {
addPrintGap("testClassExpression");
// 非java.lang包下面的Class要指明全路径
Class dateClass = PARSER.parseExpression("T(java.util.Date)").getValue(Class.class);
// String是java.lang包路径下的类,所以可以不用指明全路径
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);
System.out.println("T(java.math.RoundingMode).CEILING < T(java.math.RoundingMode).FLOOR :" + trueValue);
}
9,构造器
/**
* 构造器函数能够被new运算符调用,全路径类名需要指定,除了基础类型以及String类型
*/
public static void testConstructor() {
addPrintGap("testConstructor");
Inventor inventor = PARSER
.parseExpression("new com.ffcs.itm.web.util.springs.entity.Inventor('Albert yan','German')")
.getValue(Inventor.class);
System.out.println(
"constructor <> inventor name and nation: " + inventor.getName() + ", " + inventor.getNationality());
}
10,变量表达式
/**
* 变量在表达式中是可以被引用到的,通过#variableName。变量赋值是通过setValue在StandandExpressionContext中。
* 注意:SpEL中获取变量的值,是通过#variableName操作的,这个变量可以是任何类型,既可以是基础类型,也可以是bean实例。
* #this表示当前操作的数据对象,#root表示SpEL表达式上下文的根节点对象,这里要说明的概念就是上下文环境,
* 即StandardEvaluationContext定义的环境,虽然他不是SpEL必须定义的,但是SpEL默认是将ApplicationContext定义为根节点对象,
* 即默认#root的值为ApplicationContext。一般的,给StandardEvaluationContext指定一个对象,
* 例如本例中前半部分,将tesla作为StandardEvaluationContext的构造函数入参,即此时的#root为telsa。
*/
public static void testVariables() {
addPrintGap("testVariables");
Inventor tesla = new Inventor("Nikola Tesla", "Serbian");
StandardEvaluationContext context = new StandardEvaluationContext(tesla);
// 在StandardEvaluationContext这个上下文环境中定义一个新的变量newName,并给他赋值Mike Tesla
context.setVariable("newName", "Mike Tesla");
System.out.println("tesla name1 " + tesla.getName());
//通过getValue的方式,给javaBean赋值。
PARSER.parseExpression("name = #newName").getValue(context);
System.out.println("tesla name2 " + tesla.getName());
//#this 和 #root的介绍
// create an array of integers
List<Integer> primes = new ArrayList<Integer>();
primes.addAll(Arrays.asList(2, 3, 5, 7, 11, 13, 17));
StandardEvaluationContext contextSharp = new StandardEvaluationContext();
contextSharp.setVariable("primes", primes);
// all prime numbers > 10 from the list (using selection ?{...}),即用到集合选择的功能
// evaluates to [11, 13, 17]
List<Integer> primesGreaterThanTen = PARSER.parseExpression("#primes.?[#this>10]").getValue(contextSharp,
List.class);
primesGreaterThanTen.forEach(System.out::println);
}
11,操作符处理null
/**
* 在SpEL里面,针对下面的场景,对其做了一种简化,即当变量不等null时取变量当前值的场景。
* String name = "Elvis Presley";
* String displayName = name != null ? name : "Unknown";
* 简写成String displayName = name?: "Unknown";
*/
public static void testTernameOperator() {
addPrintGap("testTernameOperator");
Inventor tesla = new Inventor("Nikola Tesla", "Serbian");
StandardEvaluationContext context = new StandardEvaluationContext(tesla);
// 在StandardEvaluationContext这个上下文环境中定义一个新的变量newName,并给他赋值Mike Tesla
context.setVariable("newName", "Mike Tesla");
System.out.println("tesla name1 " + tesla.getName());
//通过getValue的方式,给javaBean赋值。
PARSER.parseExpression("name = #newName").getValue(context);
String expression = "name == 'Mike Tesla'?'修改实例成员变量name成功.':'修改实例成员变量name失败.'";
String name = tesla.getName();
System.out.println("tesla name2 " + name);
String result = PARSER.parseExpression(expression).getValue(context, String.class);
System.out.println("result " + result);
// 下面是验证elivs运算符的案例
name = PARSER.parseExpression("name?:'Elvis presley'").getValue(context, String.class);
System.out.println("name3 " + name);
tesla.setName(null);
name = PARSER.parseExpression("name?:'Elvis presley'").getValue(context, String.class);
System.out.println("name4 " + name);
}
12,安全导航运算符
/**
* 安全导航运算符,主要用来避免实例操作出现NullPointerException。典型的是,当你访问一个对象的实例,
* 你首先要确保这个实例不是null,才有可能去访问其方法或者属性。
* SpEL通过Safe Navigation运算符可以避免这种因为是null抛出异常,取而代之的是用null返回值。
*/
public static void testSafeNaviOperator() {
addPrintGap("testSafeNaviOperator");
Inventor tesla = new Inventor("Nikola Tesla", "Serbian");
tesla.setBirthPlace(new PlaceOfBirth("Smiljan"));
StandardEvaluationContext context = new StandardEvaluationContext(tesla);
String city = PARSER.parseExpression("birthPlace?.City").getValue(context, String.class);
System.out.println("before <> city: " + city); // Smiljan
tesla.setBirthPlace(null);
city = PARSER.parseExpression("birthPlace?.city").getValue(context, String.class);
System.out.println("after <> city: " + city); // null - does not throw NullPointerException!!!
}
13,集合选择
/**
* 集合选择是一个非常有用的表达式语言特性,它方便你实现从一个集合选择符合条件的元素放入另外一个集合中。
* 语法是:?[selectionExpression] 集合选择功能既可以用在list列表,也可以用于map结构。
* 可以通过^[selectionExpression]获取第一个成员,通过$[selectionExpression]取最后一个元素
*/
public static void testCollectionSelection() {
addPrintGap("testCollectionSelection");
//map中指定key的查找
Inventor in1 = new Inventor("zhangsan", "China");
Inventor in2 = new Inventor("wangwu", "America");
Inventor in3 = new Inventor("tesla", "Serbian");
Inventor in4 = new Inventor("lang", "Serbian");
Society society = new Society();
society.getMember().add(in1);
society.getMember().add(in2);
society.getMember().add(in3);
society.getMember().add(in4);
EvaluationContext societyContext = new StandardEvaluationContext(society);
List<Inventor> list = PARSER.parseExpression("member.?[nationality == 'Serbian']").getValue(societyContext,
List.class);
System.out.println("Inventor list count: " + list.size());
//map中基于value的条件进行查找
Map<String, Object> map = new HashMap<>();
map.put("zhangsan", 31);
map.put("lishi", 23);
map.put("wangwu", 15);
map.put("zhaoliu", 26);
society.setMguest(map);
Map<String, Object> newMap = PARSER.parseExpression("mguest.?[value < 27]").getValue(societyContext,
HashMap.class);
for (String ky : newMap.keySet()) {
System.out.println("name: " + ky + ", value: " + newMap.get(ky));
}
// 验证 .^[selectionExpression]取第一个满足条件的,.$[selectionExpression]取最后一个满足条件的
Map<String, Integer> v1 = PARSER.parseExpression("mguest.^[value<27]").getValue(societyContext, HashMap.class);
System.out.println("first element: " + v1.toString());
Map<String, Integer> v2 = PARSER.parseExpression("mguest.$[value<27]").getValue(societyContext, HashMap.class);
System.out.println("last element: " + v2.toString());
}
14,集合投射
/**
* 集合投射就是在一个集合的基础上基于一定的规则抽取出相应的数据,重新生成一个集合。表达式![projectionExpression]
* 集合投射,对map也可以适用,只是获取后的结果是一个list,里面的成员是map.entry
*/
public static void testCollectionProjection() {
addPrintGap("testCollectionProjection");
Inventor iv1 = new Inventor("Tesla", "Serbian");
iv1.setBirthPlace(new PlaceOfBirth("Buzhidao", "Serbian"));
Inventor iv2 = new Inventor("Mayun", "China");
iv2.setBirthPlace(new PlaceOfBirth("Hangzhou", "China"));
Inventor iv3 = new Inventor("Sunzhengyi", "Japan");
iv3.setBirthPlace(new PlaceOfBirth("Tokyo", "Japan"));
Society society = new Society();
society.getMember().add(iv1);
society.getMember().add(iv2);
society.getMember().add(iv3);
EvaluationContext context = new StandardEvaluationContext(society);
List<String> placesOfBirth = PARSER.parseExpression("member.![birthPlace.city]").getValue(context, List.class);
for (String pob : placesOfBirth) {
System.out.println("P O B: " + pob);
}
}
15,表达式模板
public static void testExpressionTemplating() {
addPrintGap("testExpressionTemplating");
String randomPhrase = PARSER
.parseExpression("random number is #{T(java.lang.Math).random()}", new TemplateParserContext())
.getValue(String.class);
System.out.println("Expression Template: " + randomPhrase);
}
3,注入:
注入部分目前用得不多,后续有遇上,再补上这部分。
相对于el的#{}(#{}基本语法 :#{bean.属性?:默认值},注意bean.属性必须是要存在的,当为null时匹配 ),在工作中Spring占位符的 ${} 用得更多。
${} 基本语法: ${属性:默认值},如果属性为null或者不存在的话,就是用默认值填充
比如用于获取系统文件配置的值:
private static boolean cacheSwitch;
@Value("${feign.apiOauth.enable:false}")
public void setCacheSwitch(boolean cacheSwitch) {
this.cacheSwitch = cacheSwitch;
}
系统的配置 yml文件:
feign:
apiOauth:
enable: false #开启api鉴权
4,测试:
测试:
public static void main(String[] args) {
testBase();
testInlineList();
testArray();
testRelationOperators();
testAssignment();
testClassExpression();
testConstructor();
testVariables();
testTernameOperator();
testSafeNaviOperator();
testCollectionSelection();
testCollectionProjection();
testExpressionTemplating();
}
输出
====================== testBase ======================
message:Hello World
message concat:Hello World!
字节内容:[72, 101, 108, 108, 111, 32, 87, 111, 114, 108, 100]
字节长度:11
message toUpperCase:HELLO WORLD
====================== testInlineList ======================
单独列表:[1, 2, 3, 4]
二维列表:[[a, b], [x, y]]
====================== testArray ======================
numbers1 element: 0
numbers1 element: 0
numbers1 element: 0
numbers1 element: 0
numbers2 element: 1
numbers2 element: 2
numbers2 element: 3
numbers3 dim 2 size: 5
numbers3 dim 2 size: 5
numbers3 dim 2 size: 5
numbers3 dim 2 size: 5
====================== testRelationOperators ======================
2 == 2: true
2 < -5.0: true
'black' < 'block': true
0 > null : true
-1 < null: false
'xyz' instanceof T(int): false
'5.00' matches '^\d+(\.\d{2})?$': true
'5.0067' matches '^\d+(\.\d{2})?$': false
true and false: false
true or false: true
!true: false
1 + 1: 2
'test' + ' ' + 'string': test string
1 - -3: 4
====================== testAssignment ======================
assignment <> inventor'name is: Alexander yan
assignment <> inventor'name is: Alexmandar lang Alexmandar lang
====================== testClassExpression ======================
T(java.math.RoundingMode).CEILING < T(java.math.RoundingMode).FLOOR :true
====================== testConstructor ======================
constructor <> inventor name and nation: Albert yan, German
====================== testVariables ======================
tesla name1 Nikola Tesla
tesla name2 Mike Tesla
11
13
17
====================== testTernamrOperator ======================
tesla name1 Nikola Tesla
tesla name2 Mike Tesla
result 修改实例成员变量name成功.
name3 Mike Tesla
name4 Elvis presley
====================== testSafeNaviOperator ======================
before <> city: Smiljan
after <> city: null
====================== testCollectionSelection ======================
Inventor list count: 2
name: lishi, value: 23
name: zhaoliu, value: 26
name: wangwu, value: 15
first element: {lishi=23}
last element: {wangwu=15}
====================== testCollectionProjection ======================
P O B: Buzhidao
P O B: Hangzhou
P O B: Tokyo
====================== testExpressionTemplating ======================
Expression Template: random number is 0.158212976519581
4,总结:
SpringEL 不难,但内容也不会少。熟悉其基本语法结构,如何操作了解各大概,明确其使用的场景就行。在工作上遇到了,有特别的要求的再学相应的内容,如同工具书一样,需要的时候去翻一翻。花很多时间去学,平时用不上,一段时间又忘了。学习嘛,有间隔重复,在工作上遇到了,再强化,这样感觉效果会更好些。
下一篇: SpringEL的应用场景