上海古都建筑设计集团,上海办公室装修设计公司,上海装修公司高质量的内容分享社区,上海装修公司我们不是内容生产者,我们只是上海办公室装修设计公司内容的搬运工平台

Spring SpEL在Flink中的应用-SpEL详解

guduadmin453月前

 

前言

  Spring 表达式语言 Spring Expression Language(简称 SpEL )是一个支持运行时查询和操做对象图的表达式语言 。 语法相似于 EL 表达式 ,但提供了显式方法调用和基本字符串模板函数等额外特性。SpEL 在许多组件中都得到了广泛应用,如 Spring Data、Spring Security、Spring Web Flow 等。它提供了一种非常灵活的方式来查询和操作对象图,从而简化了复杂的业务逻辑和数据操作。本系列文章介绍SpEL与Flink结合应用。


一、SpEL主要功能

  • 属性查询和设置:可以查询和设置对象的属性。例如,#root.name 查询根对象的 "name" 属性。
  • 方法调用:可以调用对象的任意方法。例如,#root.someMethod() 调用根对象的 "someMethod" 方法。
  • 条件表达式:可以使用条件表达式,如 ?>, ?, <, <=, >=, !=, == 来判断值。
  • 布尔和关系运算符:可用于布尔和关系运算。
  • 集合操作:可以用来操作集合,如 size(), contains(), any, all, isEmpty 等。
  • 自定义函数:可以注册自定义函数,并在 SpEL 表达式中调用它们。
  • 类型转换:SpEL 支持类型转换,例如 as 关键字可以用来转换类型。
  • 正则表达式:可以使用正则表达式进行模式匹配。
  • 解析 JSON:SpEL 可以解析 JSON 字符串并查询其内容。

    二、POM依赖

    首先在 pom.xml 中加入依赖:

    
       org.springframework
       spring-expression
       5.2.0.RELEASE
    

    二、SpEL应用

    1.解析字面量

        private void evaluateLiteralExpresssions() {
            Expression exp = parser.parseExpression("'Hello World'");
            String message = (String) exp.getValue();
            System.out.println(message);
            exp = parser.parseExpression("88");
            Integer value = exp.getValue(Integer.class);
            System.out.println(value*2);
        }

    2.直接文本上调用方法

    示例展示了在字符串上直接调用Java String类的public方法。

        private void methodInvocationOnLiterals() {
            Expression exp = parser.parseExpression("'Hello World'.concat('!')");
            String message = (String) exp.getValue();
            println(message);
            exp = parser.parseExpression("'Hello World'.length()");
            Integer size = exp.getValue(Integer.class);
            println(size);
            exp = parser.parseExpression("'Hello World'.split(' ')[0]");
            message = (String)exp.getValue();
            println(message);
        }

    3、访问对象属性和方法

    	private void accessingObjectProperties() {
            User user = new User("John", "Doe",  true, "john.doe@acme.com",30);
            Expression exp = parser.parseExpression("firstName");
            println((String)exp.getValue(user));
            exp = parser.parseExpression("isAdmin()==false");
            boolean isAdmin = exp.getValue(user, Boolean.class);
            println(isAdmin);
            exp = parser.parseExpression("email.split('@')[0]");
            String emailId = exp.getValue(user, String.class);
            println(emailId);
            exp = parser.parseExpression("age");
            Integer age = exp.getValue(user, Integer.class);
            println(age);
        }

    4、Json表达式

        public static void jsonExpress(){
            JSONObject json = new JSONObject();
            json.put("age",20);
            StandardEvaluationContext conetxt = new StandardEvaluationContext(json);
            SpelExpressionParser parser = new SpelExpressionParser();
            String el="get('age')>10";
            el="['age']>10";
            Expression exp = parser.parseExpression(el);
            Boolean bb=(Boolean)exp.getValue(conetxt);
            System.out.println(bb);
        }

    5、Flink Row表达式

        public static void rowExpress(){
            Row row = Row.of("name4", 6000, 104.5d);
            StandardEvaluationContext conetxt = new StandardEvaluationContext(row);
            SpelExpressionParser parser = new SpelExpressionParser();
            String el="getField(2)+getField(2)";
            Expression exp = parser.parseExpression(el);
            Object value = exp.getValue(conetxt);
            Double bb=(Double)value;
            System.out.println(bb);
        }

    6、调用自定义函数

    注册自定义函数,并调用。日期比较代码示例:

        public static void compareDate(){
            StandardEvaluationContext context = new StandardEvaluationContext(new SpelMethodUtil());
            context.setVariable("dateOne", new Date());
    //        context.setVariable("dateTwo", "2022-01-01");
            //SpEL Parser
            ExpressionParser parser = new SpelExpressionParser();
            Expression exp = parser.parseExpression("compareDate(#dateOne, \"2024-01-01\")");
            Object value = exp.getValue(context);
            System.out.println(value);
        }

    自定义函数类

    public class SpelMethodUtil {
        public static final String TIMESTAMP_FORMAT = "yyyy-MM-dd HH:mm:ss";
        public static final String DATE_FORMAT = "yyyy-MM-dd";
        public static final String TIME_FORMAT = "HH:mm:ss";
     
        public static Integer compareDate(Date date, String strDate){
            Integer result;
            if(date==null&& StringUtils.isBlank(strDate)){
                return 0;
            }else{
                if(date==null || StringUtils.isBlank(strDate)){
                    return -2;
                }
            }
            String trimDate=strDate.trim();
            String format = findFormat(trimDate);
            Date date2 = stringToDate(trimDate, format);
            result=date.compareTo(date2);
            return result;
        }
        public static Integer compareDate(Date first, Date second){
            if(first==null&& second==null){
                return 0;
            }else{
                if(first==null || second==null){
                    return -2;
                }
            }
            return first.compareTo(second);
        }
        public static Date stringToDate(String dateStr,String format){
            SimpleDateFormat sdf = new SimpleDateFormat(format);
            Date date=null;
            try {
                date= sdf.parse(dateStr);
            } catch (ParseException e) {
                e.printStackTrace();
            }
            return date;
        }
        /**
         * 查找与输入的字符型日期相匹配的format
         * @param strDate
         * @return
         */
        public static String findFormat(String strDate){
            String result=null;
            String trimDate=strDate.trim();
            int len=trimDate.length();
            String dateRegex = "";
            if(len==TIMESTAMP_FORMAT.length()){
                dateRegex = "^\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2}$";
                if(trimDate.matches(dateRegex)){
                    result=TIMESTAMP_FORMAT;
                }
            }else if(len==DATE_FORMAT.length()){
                dateRegex = "^\d{4}-\d{2}-\d{2}$";
                if(trimDate.matches(dateRegex)){
                    result=DATE_FORMAT;
                }
            }else if(len==TIME_FORMAT.length()){
                dateRegex = "^\d{2}:\d{2}:\d{2}$";
                if(trimDate.matches(dateRegex)){
                    result=TIME_FORMAT;
                }
            }else{
                throw  new RuntimeException("不可识别的日期格式!"+strDate);
            }
            return result;
        }
        public static Integer addAge(Integer age){
            return age+4;
        }
    }

    七、执行各种操作符(比较、逻辑、算术)

    SpEl支持下面几种操作:

    关系比较操作:==, !=, <, <=, >, >=

    逻辑操作: and, or, not

    算术操作: +, -, /, *, %, ^

        private void operators() {
            User user = new User("John", "Doe", true,"john.doe@acme.com",  30);
            Expression exp = parser.parseExpression("age > 18");
            println(exp.getValue(user,Boolean.class));
            exp = parser.parseExpression("age < 18 and isAdmin()");
            println(exp.getValue(user,Boolean.class));
        }

    总结

    通过示例介绍了SpEl中多种应用示例。大家可以利用这些功能实现更加灵活的功能应用。

网友评论

搜索
最新文章
热门文章
热门标签
 
 但没流血  周公解梦大全查询全部  女人梦见爬坡有人拉上去