Osgi 如何使用ServiceTracker高效地使用多个服务?

Osgi 如何使用ServiceTracker高效地使用多个服务?,osgi,Osgi,我想使用ServiceTracker来使用我们公司发布的服务。 与其为我想要使用的每个服务创建新的ServiceTracker,不如只创建一个带有过滤器的服务,然后从中获取服务: Filter filter = ctx.createFilter("(" + Constants.OBJECTCLASS + "=com.mycomp*)"); tracker = new ServiceTracker(ctx, filter, null); 这种方法的问题是,然后我需要迭代跟踪程序找到的服务引用,检

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

Filter filter = ctx.createFilter("(" + Constants.OBJECTCLASS + "=com.mycomp*)");
tracker = new ServiceTracker(ctx, filter, null);
这种方法的问题是,然后我需要迭代跟踪程序找到的服务引用,检查它们的objectClass属性,并查看是否可以将其分配给服务对象,由于需要强制转换,服务对象非常繁琐且容易出错


还有什么其他方法可以更优雅地使用多个服务吗?

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


[1] 有效Java,第2版,第29项。

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

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

@Component public class SomeMyCompComponent {
  ...
  @Reference
  void foo( com.mycomp.X x ) { ... }
  ...    
}
在这个模型中,您不需要集中维护调度器,任何类都可以在需要时获得所需的服务。该模型还可以准确地处理多个依赖项和更多优点

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


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

请参见《有效Java》第二版第29项。那里有足够的代码示例。如果你还没有这本书,你真的应该得到它!非常感谢你的见解Peter。我们正在使用Guice/Peaberry进行DI,所以我想我可以使用它们来完成所有这些工作,以便使用服务,我只是讨厌它们造成的过载服务模块和绑定。。。