par*_*tje 5 java osgi eclipse-rcp
我正在Eclipse RCP中开发一个应用程序.我需要有关服务设计的设计决策方面的帮助.
我有一些用于REngine向其他模块提供对象的bundle .它REngine是计算引擎的接口,可以通过多种方式实现.捆绑包通过连接到远程服务器或启动本地计算线程来提供REngine实例.一些捆绑包需要通过GUI进行配置(但也需要在无头平台上提供).客户端Bundle可以请求多个REngine对象进行并行计算.
我目前注册这些模块以提供REngine服务.该服务由ServiceFactory创建,该服务启动本地计算实例或远程(服务器)实例.客户负责尝试REngine该类的所有服务注册并选择正确的服务注册.
执行此操作的代码可归纳如下:
class API.REngine { ... }
class REngineProvider.Activator {
public void start(BundleContext ctx) {
ctx.registerService(REngine.class.getName(), new REngineFactory(), null);
}
}
class REngineProvider.REngineFactory implements ServiceFactory {
public Object getService(Bundle bundle, ServiceReference reference) {
return new MyREngineImplementation();
}
public void ungetService(REngine service) {
service.releaseAssociatedResources();
}
}
class RConsumer.Class {
REngine getREngine() {
ServiceReference[] references = bundleContext.getAllServiceReferences(REngine.class.getName(), null);
for(ServiceReference ref: references) {
try {
return bundleContext.getService(ref);
} catch (Exception e) {} // too bad, try the next one
}
}
}
Run Code Online (Sandbox Code Playgroud)
我想保留这个模型.很高兴OSGi服务规范符合我的业务要求,即REngine对象是生命对象,应该在不再需要时释放它们.
但是,注册服务每个包只能提供一个服务实例.第二次请求服务时,将返回一个缓存的实例(而不是创建一个新的实例).这与我的要求不符; 一个bundle应该能够从同一个提供者那里获得多个REngine对象.
我已经看过其他OSGi框架类,但似乎没有任何帮助.另一种选择是白板模型,但是注册一个REngineRequest服务似乎很奇怪,它由REngineProvider包用来提供一个实时的REngine.
我如何在OSGi中实现这一点?提醒一下,这是我的要求清单:
REngineProvider捆绑包.客户端代码将仅使用其他提供程序.REngine每个客户端捆绑包多个实例REngine实例REngine创作可能会失败.客户端模块应该能够知道原因.只是添加我选择的解决方案作为未来参考.似乎OSGi服务平台不是为"请求服务"而制作的.它是创建服务的提供程序包,以及可以查找和使用服务的客户端包.不能为每个用户请求提供服务的自动"工厂".
选择的解决方案涉及OSGi白板模型.乍一看,这似乎很难管理,但Blueprint可以帮助很多!
Provider blueprint.xml文件:
<reference-list interface="org.application.REngineRequest"
availability="optional">
<reference-listener
bind-method="bind" unbind-method="unbind">
<bean class="org.provider.REngineProvider"/>
</reference-listener>
Run Code Online (Sandbox Code Playgroud)
该类REngineRequest是一个共享API类,允许提供程序输入其REngine对象,或设置一个Exception来解释创建无效的原因.
对于客户来说,使用REngine就像现在一样简单:
REngineRequest req = new REngineRequest();
ServiceRegistration reg = bundleContext.registerService(req, REngineRequest.class.getName(), engineCreationProperties);
req.getEngine().doSomeStuff();
reg.unregister();
Run Code Online (Sandbox Code Playgroud)
我们假设提供者在客户端使用REngine时永远不会停止.如果是,则REngine变为无效.
声明性服务中的ComponentFactory正是您所需要的。大多数时候,您应该使用 DS,而不是手动注册和查找服务。
提供方应该注册 REngine 工厂服务(您不必自己实现工厂,DS 会为您完成)。消费者应该声明对 REngine 服务的一对多依赖。在运行时,所有可用的工厂都将被注入,消费者可以通过它们来创建实际的 REngine 实例。
| 归档时间: |
|
| 查看次数: |
1121 次 |
| 最近记录: |