Hadoop 源码中使用ServiceLoader

news/2024/7/7 19:57:00

java.util.ServiceLoader使用

今天在看hadoop源代的时候发现,在FileSystem中用到了java.util.ServiceLoader这个类来从配置文件中加载子类或者接口的实现类。以前从来没有使用过这个类,进去大概看了一下具体的实现。主要是从META-INF/services这个目录下的配置文件加载给定接口或者基类的实现,ServiceLoader会根据给定的类的full name来在META-INF/services下面找对应的文件,在这个文件中定义了所有这个类的子类或者接口的实现类,返回一个实例。

下面以一个具体的例子来说明一下ServiceLoader的具体使用,类似Hadoop FileSystem中的实现。

首先定义一个接口,具体如下:

[java] view plain copy

public interface IService {  
    public String sayHello();  
      
    public String getScheme();  
}  

该接口有两个子类,分别为HDFSService和LocalService:

[java] view plain copy

public class HDFSService implements IService {  
  
    @Override  
    public String sayHello() {  
        return "Hello HDFS!!";  
    }  
  
    @Override  
    public String getScheme() {  
        return "hdfs";  
    }  
}  

[java] view plain copy

public class LocalService implements IService {  
  
    @Override  
    public String sayHello() {  
        return "Hello Local!!";  
    }  
  
    @Override  
    public String getScheme() {  
        return "local";  
    }  
  
}  

需要在META-INF/services下以IService这个类的全名来新建立一个文件,文件中的内容为两个实现类的全名,如下:

[java] view plain copy

org.hadoop.java.HDFSService  
org.hadoop.java.LocalService  

所有的实现和配置都已经完成,下面写一个测试类来看一下结果:

[java] view plain copy

public class ServiceLoaderTest {  
  
    /** 
     * @param args 
     */  
    public static void main(String[] args) {  
        //need to define related class full name in /META-INF/services/....  
        ServiceLoader<IService> serviceLoader = ServiceLoader  
                .load(IService.class);  
        for (IService service : serviceLoader) {  
            System.out.println(service.getScheme()+"="+service.sayHello());  
        }  
    }  
  
}  

具体的输出来如下:

[plain] view plain copy

hdfs=Hello HDFS!!  
local=Hello Local!!  

可以看到ServiceLoader可以根据IService把定义的两个实现类找出来,返回一个ServiceLoader的实现,而ServiceLoader实现了Iterable接口,所以可以通过ServiceLoader来遍历所有在配置文件中定义的类的实例。Hadoop FileSystem就是通过这个机制来根据不同文件的scheme来返回不同的FileSystem。

FileSystem中的相关实例如下:

[java] view plain copy

private static void loadFileSystems() {  
  synchronized (FileSystem.class) {  
    if (!FILE_SYSTEMS_LOADED) {  
      ServiceLoader<FileSystem> serviceLoader = ServiceLoader.load(FileSystem.class);  
      for (FileSystem fs : serviceLoader) {  
        SERVICE_FILE_SYSTEMS.put(fs.getScheme(), fs.getClass());  
      }  
      FILE_SYSTEMS_LOADED = true;  
    }  
  }  
}  

FileSystem对应的配置如下:

[java] view plain copy

org.apache.hadoop.fs.LocalFileSystem  
org.apache.hadoop.fs.viewfs.ViewFileSystem  
org.apache.hadoop.fs.s3.S3FileSystem  
org.apache.hadoop.fs.s3native.NativeS3FileSystem  
org.apache.hadoop.fs.kfs.KosmosFileSystem  
org.apache.hadoop.fs.ftp.FTPFileSystem  
org.apache.hadoop.fs.HarFileSystem  

通过之前的测试类输出对应的scheme和class如下:

[plain] view plain copy

file=class org.apache.hadoop.fs.LocalFileSystem  
viewfs=class org.apache.hadoop.fs.viewfs.ViewFileSystem  
s3=class org.apache.hadoop.fs.s3.S3FileSystem  
s3n=class org.apache.hadoop.fs.s3native.NativeS3FileSystem  
kfs=class org.apache.hadoop.fs.kfs.KosmosFileSystem  
ftp=class org.apache.hadoop.fs.ftp.FTPFileSystem  
har=class org.apache.hadoop.fs.HarFileSystem  
hdfs=class org.apache.hadoop.hdfs.DistributedFileSystem  
hftp=class org.apache.hadoop.hdfs.HftpFileSystem  
hsftp=class org.apache.hadoop.hdfs.HsftpFileSystem  
webhdfs=class org.apache.hadoop.hdfs.web.WebHdfsFileSystem  

可以看到FileSystem会把所有的FileSystem的实现都以scheme和class来cache,之后就从这个cache中取相应的值。

因此,以后可以通过ServiceLoader来实现一些类似的功能。而不用依赖像Spring这样的第三方框架。


http://lihuaxi.xjx100.cn/news/2157987.html

相关文章

C# 两种方法截取活动窗口屏幕,实现窗体截图

方法1&#xff0c;截屏内容仅包括活动窗口界面&#xff0c;而方法2是从屏幕范围取图&#xff0c;截屏内容会包括屏幕上所有内容。例如有一些程序在桌面顶层显示半透明的悬浮窗&#xff0c;用方法2截屏就会包括这些内容&#xff0c;并不是单纯的活动窗口内容。 方法1&#xff0c…

三极管结构难?——秒了

前边我们已经学完了PN结&#xff0c;二极管&#xff0c;在分析了二极管后&#xff0c;我们对这些东西有了一定深度的了解&#xff0c;但是只给我们一个二极管去研究&#xff0c;这玩意好像真的没啥大用&#xff0c;其实我们追求的是用半导体材料去代替电子管的放大作用&#xf…

Windows 2003 R2与Windows 2022建立域信任报错:本地安全机构无法跟域控制器获得RPC连接。请检查名称是否可以解析,服务器是否可用。

在Windows Server 2003 R2与Windows Server 2022之间建立域信任时遇到“本地安全机构无法与域控制器获得RPC连接”的错误&#xff0c;可能是由于以下几种原因&#xff1a; DNS 解析问题&#xff1a; 确保源域和目标域的DNS配置正确&#xff0c;能够互相解析对方的域名和IP地址。…

TCP-IP详解卷一:协议——阅读总结

该内容适合程序员查看 第1章 概述 1.1 引言 WAN全称是 Wide Area Network&#xff0c;中文名为广域网。 LAN全称是 Local Area Network&#xff0c;中文名为局域网。 1.2分层 ICP/IP协议族通常被认为是一个四层协议系统 分层协议应用层Telnet、FTP和e-mail运输层TCP和UDP网…

爬虫入门教程(一)

爬虫入门教程 1.什么是爬虫 爬虫是一种自动获取网站数据的程序或脚本。它可以自动模拟人类访问网站,获取网页源代码,解析并提取出所需的数据。 爬虫的工作原理类似于搜索引擎的索引程序&#xff0c;它们会按照预定的规则和算法在互联网上不断地爬取网页&#xff0c;收集信息…

【JVM】JVM 虚拟机重点解析

JVM 虚拟机重点解析 1. JVM 组成 1.1 JVM 由那些部分组成&#xff0c;运行流程是什么&#xff1f; JVM是什么 Java Virtual Machine Java程序的运行环境&#xff08;java二进制字节码的运行环境&#xff09; 好处&#xff1a; 一次编写&#xff0c;到处运行 自动内存管理…

从ChatGPT到多模态大模型:现状与未来(多模态)

ChatGPT 训练的核心技术主要包括: 预训练语言模型;有监督微调;基于人类反馈的 强 化 学 习 (ReinforcementLearningfrom Human Feedback,RLHF) 首先,通过自监督预训练使语言模型从大规模语料库中学习语言规律,具备基础 理解和生成能力;然后,通过构造指令微调数据集 并对模型进…

Go导入私有仓库

使用go.mod依赖第三方库时&#xff0c;有以下要求&#xff1a; 代码仓库托管于VCS(版本控制系统)&#xff1b;代码仓库是公开的&#xff1b;仓库地址使用域名访问&#xff1b;仓库域名支持HTTPS访问。 对于自己或者公司内部搭建的私有git&#xff0c;这些条件是比较难同时满足…