IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 大数据 -> FlinkSQL源码解析(二)执行流程 -> 正文阅读

[大数据]FlinkSQL源码解析(二)执行流程

????????在前面已经了解了FlinkSQL的转换流程,即如何从excuteSql(sql)如何转换为transformation,到任务的提交。

????????整体流程大致为:sqlNode --> Operation --> RelNode --> 优化 --> execNode --> Transformation

????????现在想更深入的了解,我们书写的sql语句是如何通过connecter属性连接kafka、hdfs等,为修改源码新增connector做铺垫。

????????在这里我们先了解下Java SPI机制。

1、Java SPI机制

1.1、什么是SPI

????????SPI全称(Service Provide Interface),在JAVA中是一个比较重要的概念,在框架设计中被广泛使用。在框架设计中,要遵循的原则是对扩展开放,对修改关闭,保证框架实现对于使用者来说是黑盒。因为框架不可能做好所有的事情,只能把共性的部分抽离出来进行流程化,然后留下一些扩展点让使用者去实现,这样不同的扩展就不用修改源代码或者对框架进行定制。也就是我们经常说的面向接口编程。

????????在JDK6里面引进的一个新的特性ServiceLoader,从官方的文档来说,它主要是用来装载一系列的service provider。而且ServiceLoader可以通过service provider的配置文件来装载指定的serviceprovider。当服务的提供者,提供了服务接口的一种实现之后,我们只需要在jar包的META-INF/services/目录里同时创建一个以服务接口命名的文件。该文件里就是实现该服务接口的具体实现类。而当外部程序装配这个模块的时候,就能通过该jar包META-INF/services/里的配置文件找到具体的实现类名,并装载实例化,完成模块的注入。综上所述,SPI机制实际上就是"基于接口的编程+策略模式+配置文件"组合实现的一种动态加载机制,在JDK中提供了工具类:java.util.ServiceLoader来实现服务查找。

1.2、实现 SPI ?机制,要遵循下面的一些规范:

????????服务提供者提供了接口的具体实现后,需要在资源文件夹中创建META-INF/services文件夹,并且新建一个以全类名为名字的文本文件,文件内容为实现类的全名(如下面图中的红框);

????????接口实现类必须在工程的classpath下,也就是maven中需要加入依赖或者jar包引用到工程里。

1.3、实践案例

? ? ? ? 这里有个简单的样例,分别有接口MyService接口以及它的2个实现类MyServiceA和MyServiceB,还有个测试类TestMyServicesSPI。

? ? ? ? ?代码和配置文件信息如下:

public interface MyService {

    void doSomething();
}

public class MyServiceA implements MyService {
    @Override
    public void doSomething() {
        System.out.println("Hello,MyService A!");
    }
}

public class MyServiceB implements MyService {
    @Override
    public void doSomething() {
        System.out.println("Hello,MyService B!");
    }
}

public class TestMyServiceSPI {

    public static void main(String[] args) {
        ServiceLoader<MyService> services = ServiceLoader.load(MyService.class);
        Iterator<MyService> iterator = services.iterator();
        while (iterator.hasNext()) {
            MyService myService = iterator.next();
            myService.doSomething();
        }
    }
}

?????????我们必须要在source下面创建META-INF/services文件夹吗不放在这个位置难道就加载不到吗?答案是肯定的,如果不创建确实加载不到,因为源码里面的PREFIX="META-INF/services/"这个变量是写死的,如下图,所以我们必须创建这个文件夹.这里会遍历文件里面所有的实现类然后通过反射机制去创建对象。

????????你可能还会发现一个问题load方法一开始就获取了Thread.currentThread().getContextClassLoader()上下文的类加载器,然后一直往后面传递,最后在forName里面用到了,那如果不把loader传进来行不行?答案是确实不行,因为ServiceLoader是一个基础类,它是在java.util这个包下面的,所以它是由BootstrapClassLoader来加载的.而我们自定义的实现类是由AppClassLoader去加载的,BootstrapClassLoader这个类加载器是加载不到我们定义的类的,所以这里getContextClassLoader其实是打破了双亲委派模型的。

1.4、总结

  • 优点:SPI机制的优缺点都非常明显,优点是实现解耦,使得接口的定义和具体业务实现分离,易于动态扩展,帮忙我们灵活的插件化开发。
  • 缺点:缺点也很明显,不能按需加载,虽然ServiceLoader做了延迟加载,但是会把接口的实现类全部加载并实例化一遍,可能会造成浪费,获取某个实现类的方式比较单一,只能通过iterator形式获取,不能根据参数的形式获取。

????????

  大数据 最新文章
实现Kafka至少消费一次
亚马逊云科技:还在苦于ETL?Zero ETL的时代
初探MapReduce
【SpringBoot框架篇】32.基于注解+redis实现
Elasticsearch:如何减少 Elasticsearch 集
Go redis操作
Redis面试题
专题五 Redis高并发场景
基于GBase8s和Calcite的多数据源查询
Redis——底层数据结构原理
上一篇文章      下一篇文章      查看所有文章
加:2022-03-12 17:36:19  更:2022-03-12 17:36:47 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/24 8:42:05-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码