Spring之Spel表达式
正常业务场景一般不用这个技术,但需要知道有这么个东西支持Spring。
记忆力不好,抄了些套路代码便于以后用到。
package com.paic.phssp.springtest.spel; import java.util.Arrays; import java.util.List; public class Account { private String name; private int footballCount; private Friend friend; private List<Friend> friends; public Account(String name) { this.name = name; } public String getName() { return name; } public void setFootballCount(int footballCount) { this.footballCount = footballCount; } public void addFriend(Friend friend) { this.friend = friend; } public int getFootballCount() { return footballCount; } public Friend getFriend() { return friend; } public void setFriend(Friend friend) { this.friend = friend; } public List<Friend> getFriends() { return friends; } public void setFriends(List<Friend> friends) { this.friends = friends; } public void read(){ System.out.println("读书"); } public void addFriendNames(String ... friendNames){ System.out.println("friendNames="+ Arrays.toString(friendNames)); } }
package com.paic.phssp.springtest.spel; public class Friend { private String name; public Friend(String name) { this.name = name; } public String getName() { return name; } }
package com.paic.phssp.springtest.spel; import com.paic.phssp.springtest.proxy.cglib.HeroCglibProxyFactory; import com.paic.phssp.springtest.proxy.cglib.WickedLittleMage; import com.paic.phssp.springtest.proxy.jdk.HeroProxyFactory; import com.paic.phssp.springtest.proxy.jdk.IHero; import com.paic.phssp.springtest.proxy.jdk.MonkeyHero; import org.junit.Test; import org.junit.runner.RunWith; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.expression.EvaluationContext; import org.springframework.expression.ExpressionParser; import org.springframework.expression.spel.standard.SpelExpressionParser; import org.springframework.expression.spel.support.StandardEvaluationContext; import org.springframework.test.context.junit4.SpringRunner; import java.util.*; @RunWith(SpringRunner.class) @SpringBootTest public class SpelTest { @Test public void testTextEl() { //文字表达式 ExpressionParser parser = new SpelExpressionParser(); //字符串解析 String str = (String) parser.parseExpression("'你好'").getValue(); System.out.println(str); //整型解析 int intVal = (Integer) parser.parseExpression("0x2F").getValue(); System.out.println(intVal); //双精度浮点型解析 double doubleVal = (Double) parser.parseExpression("4329759E+22").getValue(); System.out.println(doubleVal); //布尔型解析 boolean booleanVal = (boolean) parser.parseExpression("true").getValue(); System.out.println(booleanVal); /* 你好 47 4.329759E28 true*/ } @Test public void testObjEl() { //初始化对象 Account account = new Account("Deniro"); account.setFootballCount(10); account.addFriend(new Friend("Jack")); //解析器 ExpressionParser parser = new SpelExpressionParser(); //解析上下文 EvaluationContext context = new StandardEvaluationContext(account); //获取不同类型的属性 String name = (String) parser.parseExpression("name").getValue(context); System.out.println(name); int count = (Integer) parser.parseExpression("footballCount+1").getValue(context); System.out.println(count); //获取嵌套类中的属性 String friend = (String) parser.parseExpression("friend.name").getValue(context); System.out.println(friend); /*Deniro 11 Jack*/ //安全导航操作符,能够避免空指针异常 account.setFriend(null); friend = (String) parser.parseExpression("friend?.name").getValue(context,String.class); System.out.println("friendName:" + friend);//friendName:null } @Test public void testArrMapListEl() { //解析器 ExpressionParser parser = new SpelExpressionParser(); //解析一维数组 int[] oneArray = (int[]) parser.parseExpression("new int[]{3,4,5}").getValue(); System.out.println("一维数组开始:"); for (int i : oneArray) { System.out.print(i); } System.out.println(); System.out.println("一维数组结束"); /* 一维数组开始: 345 一维数组结束*/ //这里会抛出 SpelParseException // int[][] twoArray = (int[][]) parser.parseExpression("new int[][]{3,4,5}{3,4,5}") // .getValue(); //解析 list List list = (List) parser.parseExpression("{3,4,5}").getValue(); System.out.println("list:" + list); //list:[3, 4, 5] //解析 Map Map map = (Map) parser.parseExpression("{account:'deniro',footballCount:10}").getValue(); System.out.println("map:" + map); //map:{account=deniro, footballCount=10} //解析对象中的 list final Account account = new Account("Deniro"); Friend friend1 = new Friend("Jack"); Friend friend2 = new Friend("Rose"); List<Friend> friends = new ArrayList<>(); friends.add(friend1); friends.add(friend2); account.setFriends(friends); EvaluationContext context = new StandardEvaluationContext(account); String friendName = (String) parser.parseExpression("friends[0].name").getValue(context); System.out.println("friendName:" + friendName); //friendName:Jack } @Test public void testMethodEl() { //解析器 ExpressionParser parser = new SpelExpressionParser(); //调用 String 方法 boolean isEmpty = parser.parseExpression("'Hi,everybody'.contains('Hi')").getValue(Boolean.class); System.out.println("isEmpty:" + isEmpty); /** * 调用对象相关方法 */ final Account account = new Account("Deniro"); EvaluationContext context = new StandardEvaluationContext(account); //调用公开方法 parser.parseExpression("setFootballCount(11)").getValue(context, Account.class); System.out.println("getFootballCount:" + account.getFootballCount()); //调用私有方法,抛出 SpelEvaluationException: EL1004E: Method call: Method write() cannot be found on net.deniro // .spring4.spel.Account type // parser.parseExpression("write()").getValue(context,Boolean // .class); //调用静态方法 parser.parseExpression("read()").getValue(context, Account.class); //调用待可变参数的方法 parser.parseExpression("addFriendNames('Jack','Rose')").getValue(context, Account.class); /* isEmpty:true getFootballCount:11 读书 friendNames=[Jack, Rose]*/ } @Test public void testRelationEl() { //关系操作符 //解析器 ExpressionParser parser = new SpelExpressionParser(); //数值比较 boolean result = parser.parseExpression("2>1").getValue(Boolean.class); System.out.println("2>1:" + result); //2>1:true //字符串比较 result = parser.parseExpression("'z'>'a'").getValue(Boolean.class); System.out.println("'z'>'a':" + result); //'z'>'a':true //instanceof 运算符 result = parser.parseExpression("'str' instanceof T(String)").getValue(Boolean.class); System.out.println("'str' 是否为字符串 :" + result); //'str' 是否为字符串 :true result = parser.parseExpression("1 instanceof T(Integer)").getValue(Boolean.class); System.out.println("1 是否为整型 :" + result); //1 是否为整型 :true //正则表达式 result = parser.parseExpression("22 matches '\\d{2}'").getValue(Boolean.class); System.out.println("22 是否为两位数字 :" + result); //22 是否为两位数字 :true } @Test public void testlogicEl() { //解析器 ExpressionParser parser = new SpelExpressionParser(); //与操作 boolean result = parser.parseExpression("true && true").getValue(Boolean.class); System.out.println("与操作:" + result); //或操作 result = parser.parseExpression("true || false").getValue(Boolean.class); System.out.println("或操作:" + result); parser.parseExpression("true or false").getValue(Boolean.class); System.out.println("或操作(or 关键字):" + result); //非操作 result = parser.parseExpression("!false").getValue(Boolean.class); System.out.println("非操作:" + result); } @Test public void testOperateEl() { ExpressionParser parser = new SpelExpressionParser(); //加法运算 Integer iResult = parser.parseExpression("2+3").getValue(Integer.class); System.out.println("加法运算:" + iResult); String sResult = parser.parseExpression("'Hi,'+'everybody'").getValue(String.class); System.out.println("字符串拼接运算:" + sResult); //减法运算 iResult = parser.parseExpression("2-3").getValue(Integer.class); System.out.println("减法运算:" + iResult); //乘法运算 iResult = parser.parseExpression("2*3").getValue(Integer.class); System.out.println("乘法运算:" + iResult); //除法运算 iResult = parser.parseExpression("4/2").getValue(Integer.class); System.out.println("除法运算:" + iResult); Double dResult = parser.parseExpression("4/2.5").getValue(Double.class); System.out.println("除法运算:" + dResult); //求余运算 iResult = parser.parseExpression("5%2").getValue(Integer.class); System.out.println("求余运算:" + iResult); //三元运算符 boolean result=parser.parseExpression("(1+2) == 3?true:false").getValue(Boolean.class); System.out.println("result:"+result); } @Test public void testClassEl() { ExpressionParser parser = new SpelExpressionParser(); //加载 java.lang.Integer Class integerClass=parser.parseExpression("T(Integer)").getValue(Class .class); System.out.println(integerClass==java.lang.Integer.class); //加载 net.deniro.spring4.spel.Account Class accountClass=parser.parseExpression("T(com.paic.phssp.springtest.spel.Account)") .getValue(Class .class); System.out.println(accountClass==com.paic.phssp.springtest.spel.Account.class); //调用类静态方法 double result = (double) parser.parseExpression("T(Math).abs(-2.5)").getValue(); System.out.println("result:" + result); //创建对象操作符 Account account=parser.parseExpression("new com.paic.phssp.springtest.spel.Account" + "('Deniro')").getValue(Account.class); System.out.println("name:"+account.getName()); } @Test public void testVariableEl(){ Account account = new Account("Deniro"); ExpressionParser parser = new SpelExpressionParser(); EvaluationContext context = new StandardEvaluationContext(account); //定义一个新变量,名为 newVal context.setVariable("newVal", "Jack"); //获取变量 newVal 的值,并赋值给 User 的 name 属性 parser.parseExpression("name=#newVal").getValue(context); System.out.println("getName:" + account.getName()); //this 操作符表示集合中的某个元素 List<Double> scores = new ArrayList<>(); scores.addAll(Arrays.asList(23.1, 82.3, 55.9)); context.setVariable("scores", scores);//在上下文中定义 scores 变量 List<Double> scoresGreat80 = (List<Double>) parser.parseExpression("#scores.?[#this>80]").getValue(context); System.out.println("scoresGreat80:" + scoresGreat80); } @Test public void testCollectSelectEl(){ //集合选择表达式 ExpressionParser parser = new SpelExpressionParser(); List list = (List) parser.parseExpression("{3,4,5}").getValue(); //----------------过滤 list 集合中的元素 final StandardEvaluationContext listContext = new StandardEvaluationContext(list); List<Integer> great4List = (List<Integer>) parser.parseExpression("?[#this>4]").getValue(listContext); System.out.println("great4List:" + great4List); //获取匹配元素中的第一个值 Integer first = (Integer) parser.parseExpression("^[#this>2]").getValue(listContext); System.out.println("first:" + first); //获取匹配元素中的最后一个值 Integer end = (Integer) parser.parseExpression("$[#this>2]") .getValue(listContext); System.out.println("end:" + end); //----------------过滤 Map Map<String, Double> rank = new HashMap<String, Double>(); rank.put("Deniro", 96.5); rank.put("Jack", 85.3); rank.put("Lily", 91.1); EvaluationContext context = new StandardEvaluationContext(); context.setVariable("Rank", rank); //value 大于 90 Map<String,Double> rankGreat95= (Map<String, Double>) parser.parseExpression("#Rank.?[value>90]").getValue(context); System.out.println("rankGreat95:" + rankGreat95); //key 按字母顺序,排在 L 后面 Map<String,Double> afterL= (Map<String, Double>) parser.parseExpression("#Rank.?[key>'L']").getValue(context); System.out.println("afterL:"+afterL); } }
参考:
https://www.jianshu.com/p/5537b2c86acd