OSGi 服务 - 最佳实践
我开始越来越喜欢 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] 让我的类成为服务 将
类成像为
public class DatabaseEntryViewer extends TableViewer
现在,我只需添加绑定/取消绑定方法我的 IDatabaseService 并添加一个 component.xml 并添加我的 DatabaseEntryViewer。这种方法假设有一个无参构造函数,并且我通过 OSGi-Service-Factory 创建 UI 组件。
[3] 经典方式:ServiceTracker
在我的 Activator 中注册静态 ServiceTracker 并访问它的经典方式。使用跟踪器的类必须处理动态。
目前我更喜欢第一种方法,因为这种方法不会使对象创建变得复杂,并且可以将激活器从无休止的静态服务跟踪器中节省下来。
I start loving OSGi services more and more and want to realize a lot more of my components as services. Now I'm looking for best-practice, especially for UI components.
For Listener-relations I use the whiteboard-pattern, which IMHO opinion is the best approach. However if I want more than just notifications, I can think of three possible solutions.
Imagine the following scenario:
interface IDatabaseService {
EntityManager getEntityManager();
}
[1] Whiteboard Pattern - with self setting service
I would create a new service interface:
interface IDatabaseServiceConsumer {
setDatabaseService(IDatabaseService service);
}
and create a declarative IDatabaseService component with a bindConsumer method like this
protected void bindConsumer(IDatabaseServiceConsumer consumer) {
consumer.setDatabaseService(this);
}
protected void unbindConsumer(IDatabaseServiceConsumer consumer) {
consumer.setDatabaseService(null);
}
This approach assumes that there's only one IDatabaseService.
[Update] Usage would look like this:
class MyUIClass ... {
private IDatabaseService dbService;
Consumer c = new IDatabaseServiceConsumer() {
setDatabaseService(IDatabaseService service) {
dbService = service;
}
}
Activator.registerService(IDatabaseServiceConsumer.class,c,null);
...
}
[2] Make my class a service
Image a class like
public class DatabaseEntryViewer extends TableViewer
Now, I just add bind/unbind methods for my IDatabaseService and add a component.xml and add my DatabaseEntryViewer. This approach assumes, that there is a non-argument constructor and I create the UI components via a OSGi-Service-Factory.
[3] Classic way: ServiceTracker
The classic way to register a static ServiceTracker in my Activator and access it. The class which uses the tracker must handle the dynamic.
Currently I'm favoring the first one, as this approach doesn't complicated object creation and saves the Activator from endless, static ServiceTrackers.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
我必须同意@Neil Bartlett,你的选项1是落后的。您实际上正在使用观察者/可观察模式。
第 2 种方法行不通,因为 RCP 中管理 UI 对象生命周期的方式不允许您做您想做的事情。该小部件必须作为某种视图容器(ViewPart、Dialog,...)初始化的一部分来创建。该视图部分通常通过工作台/插件机制进行配置和管理。你应该配合它,而不是反对它。
第三种选择是一个简单的选择,不一定是最好的,但很简单。
如果你使用Spring DM,那么你可以轻松完成第二点。它提供了一种方法将您的服务bean注入到您的UI视图、页面等中。您使用spring工厂来创建您的视图(如plugin.xml中所定义),它是通过Spring配置进行配置的,它能够将您的服务注入到豆。
您还可以将 SpringExtensionFactory 类使用的技术与 DI 结合起来来完成同样的事情,而无需引入另一项技术。我自己还没有尝试过,所以我无法评论其难度,尽管如果我还没有使用 Spring DM,我会尝试这样做来弥合 RCP 和 OSGi 之间的差距。
I have to agree with @Neil Bartlett, your option 1 is backward. You are in effect using an Observer/Observable pattern.
Number 2 is not going to work, since the way UI objects lifecycles are managed in RCP won't allow you to do what you want. The widget will have to be created as part of the initialization of some sort of view container (ViewPart, Dialog, ...). This view part is typically configured and managed via the Workbench/plugin mechanism. You should work with this, not against it.
Number 3 would be a simple option, not necessarily the best, but simple.
If you use Spring DM, then you can easily accomplish number 2. It provides a means to inject your service beans into your UI Views, Pages, etc. You use a spring factory to create your views (as defined in your plugin.xml), which is configured via a Spring configuration, which is capable of injecting your services into the bean.
You may also be able to combine the technique used by the SpringExtensionFactory class along with DI to accomplish the same thing, without introducing another piece of technology. I haven't tried it myself so I cannot comment on the difficulty, although it is what I would try to do to bridge the gap between RCP and OSGi if I wasn't already using Spring DM.