OSGi服务 - 最佳实践

时间:2011-10-27 16:46:51

标签: service osgi whiteboard declarative-services

我开始越来越喜欢OSGi服务,并希望将更多的组件作为服务来实现。现在我正在寻找最佳实践,尤其是UI组件。

对于听众关系,我使用白板模式,恕我直言,这是最好的方法。但是,如果我想要的不仅仅是通知,我可以考虑三种可能的解决方案。

想象一下以下场景:

interface IDatabaseService {
  EntityManager getEntityManager();
}

[1]白板模式 - 具有自我设置服务

我会创建一个新的服务接口:

interface IDatabaseServiceConsumer {
  setDatabaseService(IDatabaseService service);
}

并使用 bindConsumer 方法创建声明式IDatabaseService组件,如下所示

protected void bindConsumer(IDatabaseServiceConsumer consumer) {
 consumer.setDatabaseService(this);
}
protected void unbindConsumer(IDatabaseServiceConsumer consumer) {
 consumer.setDatabaseService(null);
}

这种方法假设只有一个IDatabaseService。

[更新] 用法如下:

class MyUIClass ... {

private IDatabaseService dbService;

Consumer c = new IDatabaseServiceConsumer() {
 setDatabaseService(IDatabaseService service) {
  dbService = service;
 }
}
Activator.registerService(IDatabaseServiceConsumer.class,c,null);
...
}

[2]让我的课程成为一项服务

这样的类

公共类DatabaseEntryViewer扩展了TableViewer

现在,我只为我的IDatabaseService添加bind / unbind方法,并添加一个component.xml并添加我的DatabaseEntryViewer。这种方法假设有一个非参数构造函数,我通过OSGi-Service-Factory创建UI组件。

[3]经典方式:ServiceTracker

在我的Activator中注册静态ServiceTracker并访问它的经典方法。使用跟踪器的类必须处理动态。

目前我赞成第一个,因为这种方法不会使对象创建变得复杂,并且会从无限的静态ServiceTrackers中保存Activator。

1 个答案:

答案 0 :(得分:2)

我必须同意@Neil Bartlett,你的选择1是落后的。您使用Observer / Observable模式生效。

数字2不起作用,因为在RCP中管理UI对象生命周期的方式将不允许您执行您想要的操作。必须创建窗口小部件作为某种视图容器(ViewPart,Dialog,...)初始化的一部分。此视图部分通常通过Workbench /插件机制进行配置和管理。你应该使用它,而不是反对它。

3号将是一个简单的选择,不一定是最好的,但很简单。

如果您使用Spring DM,则可以轻松完成数字2.它提供了将服务bean注入UI视图,页面等的方法。您可以使用spring工厂创建视图(如定义的那样)在你的plugin.xml中),它是通过Spring配置配置的,它能够将你的服务注入到bean中。

您也可以将SpringExtensionFactory类使用的技术与DI结合起来,以完成同样的事情,而无需引入另一项技术。我自己没有尝试过,所以我不能评论这个难度,虽然如果我还没有使用Spring DM的话,我会尝试去弥合RCP和OSGi之间的差距。