【问题标题】:Get an OSGi service instance from blueprint programmatically以编程方式从蓝图中获取 OSGi 服务实例
【发布时间】:2014-09-04 13:11:01
【问题描述】:

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

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

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

所以,作为回顾:

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

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

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 实例的唯一方法是将实例注入到类中 - 我遇到了类的初始问题不是有可能再次成为蓝图豆。

【问题讨论】:

    标签: java osgi blueprint-osgi


    【解决方案1】:

    只需在导出服务时设置一个属性。所以你可以过滤它。这样您就可以将您的服务实现与其他实现区分开来。

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

    【讨论】:

      猜你喜欢
      • 2017-10-23
      • 2011-01-17
      • 1970-01-01
      • 2012-08-12
      • 2010-12-31
      • 1970-01-01
      • 2012-05-15
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多