3

我是 OSGI 新手,我想了解如何注册服务?它总是通过BundleContextobject inActivator吗?有没有其他可用的方法?

假设我有一个接口IService,并且有两个实现ServiceImpl1,并且ServiceImpl2在同一个包中,我将它们注册如下。

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

但令人困惑的是我如何专门要求特定的服务实现?

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

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

4

3 回答 3

5

以声明方式注册和使用服务有其他选择。您可以使用声明式服务 (DS)蓝图服务。还有其他的,但这些是实际规范的一部分。

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

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 获得服务。如果您在动态环境中运行(这些服务正在停止和重新启动),那么每次查找服务时可能会获得不同的实现。

于 2012-12-20T15:30:56.067 回答
2

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

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

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

@Component
public class ServiceImpl2 {
    // ...

    @Reference
    public void setFoo(IService foo) {
        // ..
    }
}
于 2012-12-20T20:26:26.547 回答
1

切勿使用活化剂。带有注释的 DS 组件(参见 Neil 的回答)是迄今为止 OSGi 中的最佳实践。此外,DS 不再需要服务跟踪器。如果我必须再做一次 OSGi,就没有激活器,没有服务跟踪器,只有 DS。

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

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

在 DS 中控制服务绑定的 OSGi 机制是通过配置管理。您可以为组件注册的服务设置引用(依赖项)和排名(或属性)的目标过滤器。因此,对于 DS,这成为一个可配置的决定。

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

于 2012-12-21T08:16:29.930 回答