如何有效地使用ServiceTracker来使用多个服务?

时间:2011-03-20 11:17:29

标签: osgi

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

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

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

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

2 个答案:

答案 0 :(得分:0)

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

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

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

在此模型中,您不需要集中维护调度程序,任何类都可以在需要时获得所需的服务。该模型还可以准确地处理多个依赖项和更多好处。

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

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

答案 1 :(得分:-1)

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

[1] Effective Java,2nd Ed。,Item 29。