代码之家  ›  专栏  ›  技术社区  ›  Michael Neale

何时在类似OSGi的内容上使用ServiceLoader

  •  18
  • Michael Neale  · 技术社区  · 15 年前

    作为对依赖性过敏的人,什么时候我会使用OSGi代替内置Java 6之类的东西? http://java.sun.com/javase/6/docs/api/java/util/ServiceLoader.html (我想让插件jars直接插入)。

    (仅供参考,这是一个scala应用程序,开放的任何建议,服务加载器是相当接近我想要的)。

    2 回复  |  直到 12 年前
        1
  •  15
  •   seh Alexei    15 年前

    如果 ServiceLoader 大部分都符合您的需求,也就是说您正在通过类路径上的文件来寻找服务发现。这只是OSGi提供的一小部分。

    OSGi将允许您在应用程序运行时动态安装捆绑包、公布服务、撤销广告和卸载捆绑包。此外,作为服务的消费者,您可以通过过滤谓词查询来热切地查找它们,并检测何时提供服务提供者来来去去。这些包不需要位于类路径上,它们可以以各种形式提供;JAR文件和“分解目录”是我记得的两个。

    相比之下, 服务商 只做了一件事:它暴露了可发现的工厂。通常,您将创建一个工厂风格的接口,该接口使用一些参数来决定该提供程序是否可以提供适当的服务,例如将给定的字符集名称映射到 CharsetDecoder . 没有正式的协议可以从这样的提供者那里获取和释放服务。OSGi确实规范了消费者对服务的约束和解除约束。当新的提供程序联机时,使用者可以接收通知;当使用者获取和释放服务实例时,提供者可以接收通知。如果这个生命周期控制对您的服务很重要,并且您放弃了OSGi,那么您必须自己构建它; 服务加载程序 没那么远。

    或者,您可以采用一种更被动的声明性方法,让其中一个OSGi依赖性管理器将您所述的需求与可用的服务提供者匹配,而不是急于进行服务查找和使用。有许多依赖关系管理器可供选择。 Spring Dynamic Modules 是最有能力的人之一。

    OSGi提供了许多其他“中间件”工具。我不会在这里向你推销它们,因为你的问题主要集中在你会错过什么,因为你会选择 服务商 .

        2
  •  4
  •   Arjan Tijms Mike Van    12 年前

    正如SEH指出的,如果您只对简单的服务发现感兴趣,那么ServiceLoader是一种轻量级的方法,可以将消费者与提供者分离开来。但它并没有提供任何帮助来组合服务。

    例如,假设服务A需要使用服务B。这是一个“服务依赖性”…但是如果B不可用,A应该怎么做?在OSGi中,我们可以安排,如果B不可用,那么A也不可用——假设依赖项是必需的;我们还可以支持可选依赖项。另一方面,当使用ServiceLoader时,只要包含它的JAR在类路径上,服务A就不能控制其可用性…因此,即使没有所需的“后端”服务,它也必须提供其功能。

    ServiceLoader要记住的另一件事是尝试抽象查找机制。发布机制是非常好的、干净的和声明性的。但是查找(通过Java.UTI.Service EOLADER)像地狱一样丑陋,实现为一个类路径扫描器,如果将代码放入没有全局可见性的任何环境(如OSGi或JavaEE),则会非常糟糕。如果您的代码与此相混淆,那么稍后在OSGi上运行它会很困难。最好是写一个抽象,当时间到来时可以替换它。