`
fantaxy025025
  • 浏览: 1363251 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类

java_ServiceLoader和ClassLoader

 
阅读更多

 

ServiceLoader与ClassLoader是Java中2个即相互区别又相互联系的加载器.JVM利用ClassLoader将类载入内存,这是一个类声明周期的第一步(一个java类的完整的生命周期会经历加载、连接、初始化、使用、和卸载五个阶段,当然也有在加载或者连接之后没有被初始化就直接被使用的情况)。详情请参阅:详解Java类的生命周期

ServiceLoader又是什么呢?ServiceLoader:一个简单的服务提供者加载设施。服务 是一个熟知的接口和类(通常为抽象类)集合。服务提供者 是服务的特定实现。提供者中的类通常实现接口,并子类化在服务本身中定义的子类。服务提供者可以以扩展的形式安装在 Java 平台的实现中,也就是将 jar 文件放入任意常用的扩展目录中。也可通过将提供者加入应用程序类路径,或者通过其他某些特定于平台的方式使其可用。……唯一强制要求的是,提供者类必须具有不带参数的构造方法,以便它们可以在加载中被实例化。(注意:加载时就实例化了。)

通过在资源目录META-INF/services中放置提供者配置文件 来标识服务提供者。文件名称是服务类型的完全限定二进制名称。该文件包含一个具体提供者类的完全限定二进制名称列表,每行一个。忽略各名称周围的空格、制表符和空行。注释字符为'#'('\u0023', NUMBER SIGN);忽略每行第一个注释字符后面的所有字符。文件必须使用 UTF-8 编码。 

以延迟方式查找和实例化提供者,也就是说根据需要进行。服务加载器维护到目前为止已经加载的提供者缓存。每次调用iterator 方法返回一个迭代器,它首先按照实例化顺序生成缓存的所有元素,然后以延迟方式查找和实例化所有剩余的提供者,依次将每个提供者添加到缓存。可以通过 reload 方法清除缓存。

……

以上来源于Java API里的说明,也许说的很专业,让我们有点晕头转向,我们可以简单的认为:ServiceLoader也像ClassLoader一样,能装载类文件,但是使用时有区别,具体区别如下:

(1) ServiceLoader装载的是一系列有某种共同特征的实现类,而ClassLoader是个万能加载器;

         (本人注:注意:加载时就实例化了。)

(2)ServiceLoader装载时需要特殊的配置,使用时也与ClassLoader有所区别;

(3)ServiceLoader还实现了Iterator接口。[如有错误或不到的地方敬请指出,互相学习:)]

下面是关于ServiceLoader的简单的例子,仅供参考

(1)基础服务:IService

1
2
3
4
5
package com.service;
public interface IService {
    String sayHello();
    String getScheme();
}

 

(2)具体服务实现1:HDFSService

1
2
3
4
5
6
7
8
9
10
11
12
package com.impl;
import com.service.IService;
public class HDFSService implements IService {
    @Override
    public String sayHello() {
        return "Hello HDFSService";
    }
    @Override
    public String getScheme() {
        return "hdfs";
    }
}

 

(3)具体服务实现2:LocalService

 

1
2
3
4
5
6
7
8
9
10
11
12
package com.impl;
import com.service.IService;
public class LocalService  implements IService {
    @Override
    public String sayHello() {
        return "Hello LocalService";
    }
    @Override
    public String getScheme() {
        return "local";
    }
}

(4)配置:META-INF/services/com.service.IService

 

 

1
2
com.impl.HDFSService
com.impl.LocalService

(5)测试类

1
2
3
4
5
6
7
8
9
10
11
package com.test;
import java.util.ServiceLoader;
import com.service.IService;
public class Test {
    public static void main(String[] args) {
        ServiceLoader<IService> serviceLoader  = ServiceLoader.load(IService.class);
        for (IService service : serviceLoader) {
            System.out.println(service.getScheme()+"="+service.sayHello());
        }
    }
}

 

结果:

hdfs=Hello HDFSService
local=Hello LocalService

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

 

prefer: http://my.oschina.net/hanzhankang/blog/109794

 

+

+

+

0

+

+

+

 

分享到:
评论

相关推荐

    ServiceLoader的使用

    ServiceLoader内部使用了`java.util.Iterator`来迭代加载服务,通过`ClassLoader`查找配置文件,并使用`Properties`类读取实现类的列表。加载过程是在第一次调用`iterator()`时完成的,后续的迭代都是从缓存中获取。...

    Java类加载器学习总结.pdf

    为了实现SPI,通常会使用`java.util.ServiceLoader`类,这个类利用了线程上下文类加载器来查找和加载实现类。 类加载器的双亲委托模型虽然在大多数情况下能很好地工作,但在某些特定场景下,如插件系统、模块化系统...

    Java类加载及SPI机制.pdf

    Java类加载机制和SPI(ServiceProviderInterface)机制是Java平台中极其重要的两个概念,它们对于Java程序的灵活性和可扩展性起到关键作用。下面详细解释这两个机制的概念、原理和应用场景。 类加载机制是Java...

    Java类加载及SPI机制.zip

    Java虚拟机提供了三种类型的类加载器:引导类加载器(Bootstrap ClassLoader)、扩展类加载器(Extension ClassLoader)和应用程序类加载器(Application ClassLoader)。它们遵循双亲委托模型,即子类加载器先尝试...

    j2se6.rar_Looking Up

    标题“j2se6.rar_Looking Up”和描述“api for looking up java codes”暗示了这个压缩包可能包含了与Java SE 6相关的API文档,特别是关于查找或搜索Java代码方面的内容。Java SE(标准版)是Java平台的核心部分,...

    在可执行jar中载入第三方jar的几个解决方法

    4. **使用`java.util.ServiceLoader`**:对于依赖于服务提供者接口(SPI)的情况,可以利用`ServiceLoader`来加载第三方JAR提供的服务。`ServiceLoader`会遍历指定的META-INF/services/目录下的文件,根据文件内容...

    扫描Class文件的方法

    3. **Java SPI服务发现**:通过`java.util.ServiceLoader`可以发现实现特定接口的类,适用于插件化系统。 4. **ASM、ByteBuddy等字节码库**:这些库允许直接操作字节码,可以在加载Class之前进行扫描,适合于动态...

Global site tag (gtag.js) - Google Analytics