Spring SpEL在Flink中的应用-与Filter结合实现数据动态分流

这篇具有很好参考价值的文章主要介绍了Spring SpEL在Flink中的应用-与Filter结合实现数据动态分流。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。


前言

SpEL表达式与Flink fiter结合可以实现基于表达式的灵活动态过滤。有关SpEL表达式的使用请参考Spring SpEL在Flink中的应用-SpEL详解
可以将过滤规则放入数据库,根据不同的数据设置不同的过滤表达式,从而实现只需修改过滤表达式不用修改Flink代码的功能。对于基于Flink进行数据计算平台建设会起到事半功倍的效果。


一、POM依赖

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

<dependency>
   <groupId>org.springframework</groupId>
   <artifactId>spring-expression</artifactId>
   <version>5.2.0.RELEASE</version>
</dependency>

二、主函数代码示例


import org.apache.flink.streaming.api.datastream.DataStreamSource;
import org.apache.flink.streaming.api.datastream.SingleOutputStreamOperator;
import org.apache.flink.streaming.api.environment.StreamExecutionEnvironment;
import org.apache.flink.types.Row;

import java.text.SimpleDateFormat;

public class FlinkSpelFilterDemo {
    public static void main(String[] args) throws Exception {
        StreamExecutionEnvironment env = StreamExecutionEnvironment.getExecutionEnvironment();
        Row row=Row.of("张三","001",getTimestamp("2016-10-24 21:59:06"),23);
        Row row2=Row.of("张三","002",getTimestamp("2016-10-24 21:50:06"),33);
        Row row3=Row.of("张三","003",getTimestamp("2016-10-24 21:51:06"),43);
        Row row4=Row.of("李四","004",getTimestamp("2016-10-24 21:50:56"),13);
        Row row5=Row.of("李四","005",getTimestamp("2016-10-24 00:48:36"),53);
        Row row6=Row.of("李四","006",getTimestamp("2016-10-24 00:48:36"),34);
        Row row7=Row.of("李四","007",getTimestamp("2016-10-24 00:48:36"),23);
        Row row8=Row.of("李四","008",getTimestamp("2016-10-24 00:48:36"),26);
        Row row9=Row.of("李四","009",getTimestamp("2016-10-24 00:48:36"),63);

        DataStreamSource<Row> source =env.fromElements(row,row2,row3,row4,row5,row6,row7,row8,row9);
        //spel表达式,实现日期的比较过滤
        String spel="compareDate(#row.getField(2), \"2016-10-24 00:48:36\")==0";
        //实现对数字的过滤
//        spel="#row.getField(3)>33";
        SingleOutputStreamOperator<Row> filterStream = source.filter(new FilterSpelFunction(spel));
        filterStream.print();
        env.execute();
    }
    private static java.sql.Timestamp getTimestamp(String str) throws Exception {
//		String string = "2016-10-24 21:59:06";
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        java.util.Date date=sdf.parse(str);
        java.sql.Timestamp s = new java.sql.Timestamp(date.getTime());
        return s;
    }

三、FilterFunction实现


import org.apache.flink.api.common.functions.RichFilterFunction;
import org.apache.flink.configuration.Configuration;
import org.apache.flink.types.Row;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.expression.Expression;
import org.springframework.expression.spel.standard.SpelExpressionParser;
import org.springframework.expression.spel.support.StandardEvaluationContext;
import spel.demo.util.SpelMethodUtil;

/**
 * 基于spel 表达式的过滤
 */
public class FilterSpelFunction extends RichFilterFunction<Row> {
    private static final Logger logger = LoggerFactory.getLogger(FilterSpelFunction.class);

    private transient Expression exp;
    private String filterExpr;
    public FilterSpelFunction(String filterSpel) {

        filterExpr=filterSpel;
        logger.info("filterExpr:{}",filterExpr);
    }

    @Override
    public void open(Configuration parameters) throws Exception {
        super.open(parameters);
        SpelExpressionParser parser = new SpelExpressionParser();
        exp = parser.parseExpression(filterExpr);
    }

    @Override
    public boolean filter(Row row) throws Exception {
        try {
        //注册自定义函数类
            StandardEvaluationContext conetxt = new StandardEvaluationContext(new SpelMethodUtil());
            //设置变量
            conetxt.setVariable("row",row);
            Boolean value = exp.getValue(conetxt, Boolean.class);
            if (value == null) {
                logger.error("表达式结果为null");
                throw new Exception("表达式结果为null");
            }
            return value;
        }catch (Exception e){
            logger.error("filter 异常", e);
            throw e;
        }
    }
}

自定义函数类


import org.apache.commons.lang3.StringUtils;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;

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;
    }
}


总结

以上只是简单的示例,在实际应用中可以将过滤表达式放到数据库,将过滤规则放入缓存定时刷新。大家可以根据实际需求进行扩展。文章来源地址https://www.toymoban.com/news/detail-824401.html

到了这里,关于Spring SpEL在Flink中的应用-与Filter结合实现数据动态分流的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 【SpringBoot应用篇】【AOP+注解】SpringBoot+SpEL表达式基于注解实现权限控制

    Spring 表达式语言 SpEL 是一种非常强大的表达式语言,它支持在运行时查询和操作对象图。 它提供了许多高级功能,例如方法调用和基本的字符串模板功能。 表达式语言给静态Java语言增加了动态功能。 Spring 表达式语言最初是为 Spring 社区创建的,它拥有一种受良好支持的表

    2024年02月20日
    浏览(27)
  • 【Spring Boot 使用Filter统一处理请求数据转换】

    Spring Boot Filter 使用场景 身份验证和授权 场景描述: 在用户访问应用程序的敏感资源之前,需要验证用户的身份并授权用户访问特定的内容。 实现方式: 使用Filter拦截请求,检查HTTP请求中的身份验证令牌(如JWT),并确定用户是否具有执行操作的权限。 日志记录和审计 场景

    2024年02月21日
    浏览(30)
  • Spring表达式语言(SPEL)学习(03)

    在表达式中直接写name和getName(),这时候Expression是无法解析的,因为其不知道name和getName()对应什么意思 当表达式是基于某一个对象时,我们可以把对应的对象作为一个rootObject传递给对应的Experssion进行取值 通过指定EvaluationContext我们可以让name和getName()变得有意义,指定了Ev

    2024年02月02日
    浏览(35)
  • javaee spring依赖注入之spel方式

    2024年02月11日
    浏览(28)
  • 揭秘Spring依赖注入和SpEL表达式

    摘要: 在本文中,我们深入探讨了Spring框架中的属性注入技术,包括setter注入、构造器注入、注解式属性注入,以及使用SpEL表达式进行属性注入。 本文分享自华为云社区《Spring高手之路3——揭秘Spring依赖注入和SpEL表达式》,作者:砖业洋__ 。 在本文中,我们深入探讨了

    2024年02月08日
    浏览(27)
  • Spring高手之路3——揭秘Spring依赖注入和SpEL表达式

    本篇会给大家举出各种 Spring 属性依赖注入的例子,方便大家理解。 我们在前面的文章中已经使用过 XML 进行 setter 方法的属性注入了,下面让我们再来回顾一下: 我们在前面的文章中也学习过如何在 bean 创建时通过编程方式设置属性: 使用XML进行setter方法注入 首先,我们需

    2024年02月08日
    浏览(31)
  • Spring判断方法名是符合给定的SPEL+表达式的+API

    org.springframework.expression.spel.standard.SpelExpressionParser解析SPEL表达式 org.springframework.expression.spel.support.StandardEvaluationContext 验证方法名是否符合表达式 我们先使用SpelExpressionParser类来解析表达式,然后再创建一个StandardEvaluationContext对象,并将方法名作为变量设置到上下文中。最后

    2024年02月10日
    浏览(29)
  • Apache Hudi初探(三)(与flink的结合)--flink写hudi的操作(真正的写数据)

    在之前的文章中Apache Hudi初探(二)(与flink的结合)–flink写hudi的操作(JobManager端的提交操作) 有说到写hudi数据会涉及到 写hudi真实数据 以及 写hudi元数据 ,这篇文章来说一下具体的实现 这里的操作就是在 HoodieFlinkWriteClient.upsert 方法: initTable 初始化HoodieFlinkTable preWrite 在这里几乎没

    2024年02月10日
    浏览(23)
  • 在 Spring Boot 应用程序中将 MapStruct 与 Lombok 结合使用的方法

    在本文中,您将找到有关如何高效使用 MapStruct、Lombok 和 Spring Boot 的代码示例和说明。         当您实现任何规模的服务时,您通常需要将数据从一种结构移动到另一种结构。通常,这是在不同逻辑层使用的相同数据 - 在业务逻辑、数据库级别或用于传输到前端应用程序

    2024年02月14日
    浏览(25)
  • 数字化人才管理的人工智能与大数据与云计算结合应用:如何实现人力资源管理的智能化与云化...

    随着全球经济的快速发展,人力资源管理(HRM)在企业中的重要性不断提高。传统的人力资源管理方法已经不能满足企业在竞争中的需求,因此,人工智能(AI)、大数据和云计算等新技术逐渐被应用于人力资源管理领域,以实现人力资源管理的智能化与云化。 在这篇文章中,我们

    2024年04月11日
    浏览(40)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包