我开始越来越喜欢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。
答案 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之间的差距。