以编程方式从蓝图获取OSGi服务实例

时间:2014-07-14 15:01:37

标签: java osgi blueprint-osgi

我有一个java类,我需要完全控制实例化的时间和地点 - 因此我无法将其初始化为蓝图bean。

在与该类相同的包中,我有一个bean,我将其导出为OSGi服务。我需要从之前解释的非蓝图类中访问该服务实例。

我不能只执行服务查找,因为还有其他服务实现相同的接口。创建服务类的第二个(内部)实例也不起作用。

所以,作为回顾:

  • 在我使用蓝图之前,我将服务实现作为经典单例,使我能够在激活器类中注册相同的实例作为服务,以后我可以从包中访问。但是使用蓝图(据我所知)使服务类成为“经典”单例是不可能的,因为蓝图不可能创建服务实例
  • 我无法执行服务查找,因为已注册多个服务实现服务接口。

我目前的解决方案是查询实现接口的所有服务并循环列表以找到我想要的一个类的实例。

BundleContext ctx = FrameworkUtil.getBundle(getClass()).getBundleContext();
ServiceReference<?>[] refs = ctx.getServiceReferences(ServiceInterface.class.getName(), null);
ServiceImpl provider = null;
for (ServiceReference ref : refs) {
    if (ctx.getService(ref) instanceof ServiceImpl) {
        provider = (ServiceImpl) ctx.getService(ref);
    }
}

但我并不喜欢这种方法的想法。

有没有更好的方法来解决这个问题?也许某种方式直接从蓝图容器请求服务实例?我发现接口BlueprintContainer有一个通过它们获得的ID来获取实例的方法 - 但是再次获得我发现的BlueprintContainer实例的唯一方法是在类中注入实例 - 我在那里遇到了类的初始问题而不是可能再次成为蓝图豆。

1 个答案:

答案 0 :(得分:2)

在导出服务时设置属性。所以你可以过滤它。这样,您就可以将服务impl与其他服务区分开来。

我还建议您使用ServiceTracker进行服务。因此,您不必为每次调用服务处理查找。如果您不使用ServiceTracker,请确保在使用后取消该服务。

相关问题