【问题标题】:How to consume multiple services using ServiceTracker efficiently?如何使用 ServiceTracker 有效地使用多个服务?
【发布时间】:2011-03-20 11:17:29
【问题描述】:

我想使用 ServiceTracker 来使用我们公司发布的服务。 与其为我想要使用的每个服务创建新的 ServiceTracker,我认为最好只创建一个带有过滤器的服务,然后从中获取服务:

Filter filter = ctx.createFilter("(" + Constants.OBJECTCLASS + "=com.mycomp*)");
tracker = new ServiceTracker(ctx, filter, null);

这种方法的问题是,我需要遍历跟踪器发现的服务引用,检查它们的 objectClass 属性,看看我是否可以将它分配给服务对象,这非常麻烦并且由于强制转换而容易出错必填。

任何其他想法如何使用更优雅的方式来计算多个服务?

【问题讨论】:

    标签: osgi


    【解决方案1】:

    我认为这是错误的问题 :-) 从问题中我推断您有一种方法可以从您的公司获取服务,并且您希望调用该方法。也就是说,您需要在代码中的某处了解特定类型 com.mycomp.X,也就是说,您对公司的一般服务不感兴趣,您有明确的类型依赖性。在您的问题中,您假设它们需要集中调度,这通常不可靠、容易出错并且是维护热点;每次您有新的公司服务时,您都需要更新调度方法。

    一个更好的解决方案似乎是使用声明式服务并使用带有注释的 bndtools。在该模型中,您需要服务的每个地方:

    @Component public class SomeMyCompComponent {
      ...
      @Reference
      void foo( com.mycomp.X x ) { ... }
      ...    
    }
    

    在这个模型中,你不需要集中维护一个dispatcher,任何类都可以在需要的时候得到它需要的服务。该模型还可以准确处理多个依赖项和更多好东西。

    也许我没有正确理解问题,因为我从您需要的解决方案中推断出问题。但是,我认为您试图滥用服务跟踪器来完成它不打算执行的任务。

    不幸的是,DS 没有像我们应该做的那样内置到框架中:-(

    【讨论】:

    • 非常感谢彼得的洞察力。我们将 Guice/Peaberry 用于 DI,所以我想我可以使用它们来完成所有这些以使用服务,我只是讨厌他们使用 ServiceModule 和 Bindings 创建的重载......
    【解决方案2】:

    您可以继承 ServiceTracker 并添加方法以提供对您感兴趣的服务类型的直接访问。例如,您可以将服务存储在类型安全的异构容器 [1] 中。然后,您就可以调用 ServiceTracker 子类上的方法,该方法采用您感兴趣的服务类型,并且可以在类型安全的异构容器中轻松查找它们。

    [1] Effective Java,第 2 版,第 29 条。

    【讨论】:

    • 参见 Effective Java,第 2 版中的第 29 项。那里有足够的代码示例。如果你还没有这本书,你真的应该得到它!
    猜你喜欢
    • 2011-07-19
    • 1970-01-01
    • 2010-12-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-03-27
    • 1970-01-01
    相关资源
    最近更新 更多