Chr*_*oph 5 java service osgi declarative equinox
我刚刚开始使用Equinox和Eclipse PDE的OSGI和声明服务(DS).
我有2个Bundle,A和B. Bundle A公开了Bundle B使用的组件.这两个bundle也将这个服务再次公开给OSGI Service注册表.
到目前为止,一切正常,Equinox将组件连接在一起,这意味着Bundle A和Bundle B由Equinox实现(通过调用默认构造函数),然后使用bind/unbind方法进行连线.
现在,由于Equinox正在创建这些组件/服务的实例,我想知道获取此实例的最佳方法是什么?
所以假设有第三个类没有被OSGI实例化:
Class WantsToUseComponentB{
public void doSomethingWithComponentB(){
// how do I get componentB??? Something like this maybe?
ComponentB component = (ComponentB)someComponentRegistry.getComponent(ComponentB.class.getName());
}
我现在看到以下选项:
1.使用Activator中的ServiceTracker来获取ComponentBundleA.class.getName()的服务(我已经尝试了它并且它可以工作,但对我来说似乎有很多开销)并通过静态工厂方法使其可用
public class Activator{
private static ServiceTracker componentBServiceTracker;
public void start(BundleContext context){
componentBServiceTracker = new ServiceTracker(context, ComponentB.class.getName(),null);
}
public static ComponentB getComponentB(){
return (ComponentB)componentBServiceTracker.getService();
};
}
2.创建某种注册表,其中每个组件在调用activate()方法后立即注册.
public ComponentB{
public void bind(ComponentA componentA){
someRegistry.registerComponent(this);
}
要么
public ComponentB{
public void activate(ComponentContext context){
someRegistry.registerComponent(this);
}
}
}
3.使用osgi/equinox中具有这些实例的现有注册表?我的意思是OSGI已经在创建实例并将它们连接在一起,所以它已经有了某些对象.但是哪里?我怎么能得到它们?
结束语 类WantsToUseComponentB(不是组件而不是OSGI实例化)从哪里获取ComponentB的实例?有任何模式或最佳实践吗?正如我所说,我设法在Activator中使用ServiceTracker,但我认为没有它就可以实现.
我所寻找的其实是像springframework的的BeanContainer,在这里我只能说像Container.getBean(ComponentA.BEAN_NAME).但我不想使用Spring DS.
我希望这很清楚.否则我也可以发布一些源代码来更详细地解释.
谢谢Christoph
更新: 回答尼尔的评论:
感谢您针对原始版本澄清此问题,但我认为您仍需要说明为什么不能通过DS之类的东西创建第三个类.
嗯不知道.也许有一种方法,但我需要重构我的整个框架基于DS,因此不再有"新的MyThirdClass(arg1,arg2)"语句.不知道该怎么做,但我在DS中读到了有关ComponentFactories的内容.所以不要做一个
MyThirdClass object = new MyThirdClass(arg1, arg2);
我可能会这样做
ComponentFactory myThirdClassFactory = myThirdClassServiceTracker.getService(); // returns a
if (myThirdClassFactory != null){
MyThirdClass object = objectFactory.newInstance();
object.setArg1("arg1");
object.setArg2("arg2");
}
else{
// here I can assume that some service of ComponentA or B went away so MyThirdClass Componenent cannot be created as there are missing dependencies?
}
在撰写本文时,我不知道如何使用ComponentFactories,但这应该是某种伪代码:)
谢谢Christoph
克里斯托夫,
感谢您针对原始版本澄清此问题,但我认为您仍需要说明为什么不能通过DS之类的东西创建第三个类.
DS导致组件作为服务发布,因此从DS"获取"任何组件的唯一方法是通过服务注册表访问它.遗憾的是,使用较低级别的API可能难以正确使用服务注册表,因为它是动态的,因此您必须应对服务消失的可能性或者在您希望它们可用的那一刻不可用,等等.这就是DS存在的原因:它为您提供依赖服务的抽象,并根据它们引用的服务的可用性管理组件的生命周期.
如果你确实需要在不使用DS或类似东西的情况下访问服务(并且有很多类似的东西,例如Spring-DM,iPOJO,Guice/Peaberry等),那么你应该使用ServiceTracker.我同意有很多开销 - 再次,这就是DS存在的原因.
要回答你的建议no(2),不应该创建自己的服务注册表,因为服务注册表已经存在.如果您创建了一个单独的并行注册表,那么您仍然需要处理所有动态,但是您必须在两个地方而不是一个地方处理它.这同样适用于建议(3).
我希望这有帮助.
此致,尼尔
更新:顺便提一下,虽然Spring有Container.getBean()后门,但是你注意到在所有Spring文档中强烈建议不要使用后门:获取Spring bean,只需创建另一个引用它的bean.这同样适用于DS,即获取DS组件的最佳方法是创建另一个DS组件.
另请注意,在OSGi世界中,即使您使用Spring-DM,也没有简单的方法来调用getBean(),因为您需要首先获取Spring ApplicationContext.这本身就是一个OSGi服务,那么如何获得该服务呢?
| 归档时间: |
|
| 查看次数: |
8399 次 |
| 最近记录: |