我们可以简单的认为:ServiceLoader也像ClassLoader一样,能装载类文件,但是使用时有区别,具体区别如下:
- ServiceLoader装载的是一系列有某种共同特征的实现类,而ClassLoader-是个万能加载器;
- ServiceLoader装载时需要特殊的配置,使用时也与ClassLoader有所区别;
- ServiceLoader还实现了Iterator接口。
基础服务接口:IEat
public interface IEat {
void Apple();
String Banana(int i);
}
具体服务实现1:IEatImp1
public class IEatImp1 implements IEat{
public void Apple() {
System.out.println("good!!!!!!");
}
public String Banana(int i) {
return "i";
}
}
具体服务实现2:IEatImp2
public class IEatImp2 implements IEat{
public void Apple() {
System.out.println("bad!!!");
}
public String Banana(int i) {
return "i";
}
}
配置:META-INF/services/spi.IEat
spi.IEatImp1
spi.IEatImp2
测试类:main
public class main {
private static IEat it;
public static void main(String[] args) {
ServiceLoader<IEat> slr = ServiceLoader.load(IEat.class);
Iterator<IEat> iterator = slr.iterator();
while (iterator.hasNext()){
it = iterator.next();
it.Apple();
System.out.println(it.Banana(1));
}
}
}
结果:
good!!!!!!
i
bad!!!
i
ServiceLoader的应用
(1)Hadoop FileSystem
Hadoop FileSystem就是通过这个机制来根据不同文件的scheme来返回不同的FileSystem。
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;
}
}
}
对应的配置文件:
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如下:
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这样的第三方框架。