zoukankan      html  css  js  c++  java
  • 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

  • 相关阅读:
    关于HashMap初始化容量问题
    nohu和&
    (转)ShardedJedisPool的使用
    Mysql 索引问题-日期索引使用
    mysql 索引 大于等于 走不走索引 最左前缀
    tomcat开启https协议
    Hystrix的原理与使用
    Hystrix使用Commond的三种方式
    Redis 面试题(持续更新)
    如何进行用户访谈更容易获得全面而有效的信息
  • 原文地址:https://www.cnblogs.com/xiaozhuanfeng/p/10564026.html
Copyright © 2011-2022 走看看