注册服务并寻找服务

时间:2012-12-20 14:26:31

标签: java osgi

我是OSGI的新手,我想了解如何注册服务?总是通过BundleContext中的Activator对象吗?有没有替代方法?

假设我有一个接口IService,并且在同一个捆绑包中有两个实现ServiceImpl1ServiceImpl2我正在注册它们,如下所示。

context.registerService(IService.class.getName(), new ServiceImpl1(), props);
context.registerService(IService.class.getName(), new ServiceImpl2(), props);

但混淆是我如何具体要求特定的服务实施?

serviceImplObject = (IService) dictionaryServiceTracker.getService();</pre>

我不确定在这种情况下我会得到哪种实现方式。另外我没有看到任何选项来设置我需要什么类型的服务实现?

3 个答案:

答案 0 :(得分:5)

还有以声明方式注册和使用服务的替代方案。您可以使用Declarative Services (DS)Blueprint Services。还有其他一些,但这些都是实际规范的一部分。

至于您目前正在使用的程序方法。您必须在注册时使用属性,并在创建跟踪器时使用过滤器。

Map<String, String. prop1 = new HashMap<String, String>();
prop1.put("name", "primary");
context.registerService(IService.class.getName(), new ServiceImpl1(), prop1);

Map<String, String. prop2 = new HashMap<String, String>();
prop1.put("name", "secondary");
context.registerService(IService.class.getName(), new ServiceImpl2(), props);

现在进行查找。

ServiceTracker primaryTracker = new ServiceTracker(bundleContext, "(&(objectClass=my.service.Service)(name=primary))", null);
ServiceTracker secondaryTracker = new ServiceTracker(bundleContext, "(&(objectClass=my.service.Service)(name=secondary))", null);

(关于排名更新 - 感谢Neil) 如果没有过滤器,您将根据其排名和服务ID获取服务。如果您在动态环境中运行(这些服务正在停止并重新启动),那么每次查询服务时都可以获得不同的实现。

答案 1 :(得分:2)

这是注册服务的简便方法。它使用声明性服务和bnd提供的注释:

@Component
public class ServiceImpl implements IService {
    // ...
}

现在,ServiceImpl类将被实例化并作为服务发布。对于使用服务,它看起来像这样(在最简单的情况下):

@Component
public class ServiceImpl2 {
    // ...

    @Reference
    public void setFoo(IService foo) {
        // ..
    }
}

答案 2 :(得分:1)

切勿使用激活剂。带有注释的DS组件(参见Neil的答案)是OSGi中的最佳实践。此外,DS不再需要服务跟踪器。如果我不得不再次使用OSGi,那么就没有激活器,没有服务跟踪器,只有DS。

现在关于服务选择。最糟糕的OSGi组件是想要聪明并选择特定实现的组件。如果您依赖IService,那么您不应该关心您获得的实现。如果您确实需要Impl1,请指定对Impl1的依赖关系。如果您尝试做出这些决定,则会使组件的可重用性显着降低。我通过删除这种代码显着提高公司可重用性的次数令人惊讶。

DS最酷的一个方面是它允许部署者(控制框中的那个)决定应该将哪些服务绑定到谁。由于这些人对他们的世界有更多的了解,因此您作为开发人员会将其留给他们。

用于控制DS中服务绑定的OSGi机制是通过Configuration Admin。您可以为组件注册的服务设置引用(依赖项)和排名(或属性)的目标筛选器。因此,使用DS,这将成为可配置的决策。

同样,我强烈建议终止所有这些选择代码,除非进行选择的信息实际上是您域的一部分。在这种情况下,获取所有服务,只需在绑定方法中过滤它们。