OSGi 服务 - 最佳实践

发布于 2024-12-12 01:10:47 字数 1519 浏览 1 评论 0原文

我开始越来越喜欢 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 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

花开柳相依 2024-12-19 01:10:47

我必须同意@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.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文