我刚刚开始使用 Equinox 和 Eclipse PDE 使用 OSGI 和声明式服务 (DS)。
我有 2 个捆绑包,A 和 B。捆绑包 A 公开了一个由捆绑包 B 使用的组件。两个捆绑包也再次将此服务公开给 OSGI 服务注册表。
到目前为止一切正常,Equinox 正在将组件连接在一起,这意味着 Bundle A 和 Bundle B 由 Equinox 实例化(通过调用默认构造函数),然后使用 bind / unbind 方法进行连接。
现在,由于 Equinox 正在创建这些组件/服务的实例,我想知道获取此实例的最佳方法是什么?
所以假设有没有被 OSGI 实例化的第三类:
类 WantsToUseComponentB{ 公共无效 doSomethingWithComponentB(){ // 我如何获得组件B???可能是这样的? ComponentB 组件 = (ComponentB)someComponentRegistry.getComponent(ComponentB.class.getName()); }
我现在看到以下选项:
1. 在 Activator 中使用 ServiceTracker来获取 ComponentBundleA.class.getName() 的服务(我已经尝试过了,它可以工作,但对我来说似乎开销很大)并通过静态工厂方法使其可用
公共类激活器{ 私有静态ServiceTracker组件BServiceTracker; 公共无效开始(BundleContext上下文){ componentBServiceTracker = new ServiceTracker(context, ComponentB.class.getName(),null); } 公共静态组件B getComponentB(){ 返回 (ComponentB)componentBServiceTracker.getService(); }; }
2. 创建某种注册表,其中每个组件在调用 activate() 方法后立即注册。
公共组件B{ 公共无效绑定(组件A组件A){ someRegistry.registerComponent(this); }
或者
公共组件B{ 公共无效激活(组件上下文上下文){ someRegistry.registerComponent(this); } }
}
3. 使用 osgi / equinox 中的现有注册表,其中包含这些实例?我的意思是 OSGI 已经在创建实例并将它们连接在一起,所以它已经在某个地方拥有了对象。但是哪里?我怎样才能得到它们?
结论WantsToUseComponentB 类(不是组件,也不是由 OSGI 实例化)从哪里获得 ComponentB 的实例?是否有任何模式或最佳实践?正如我所说,我设法在 Activator 中使用了 ServiceTracker,但我认为没有它也是可能的。
我正在寻找的实际上是类似 Springframework 的 BeanContainer 之类的东西,在这里我可以说类似 Container.getBean(ComponentA.BEAN_NAME) 之类的东西。但我不想使用 Spring DS。
我希望这已经足够清楚了。否则我也可以发布一些源代码来更详细地解释。
谢谢克里斯托夫
更新: 对尼尔评论的回答:
感谢您针对原始版本澄清这个问题,但我认为您仍然需要说明为什么不能通过 DS 之类的东西创建第三类。
嗯不知道。也许有一种方法,但我需要将我的整个框架重构为基于 DS,以便不再有“new MyThirdClass(arg1, arg2)”语句。真的不知道该怎么做,但我在 DS 中读到了一些关于 ComponentFactories 的内容。所以而不是做一个
MyThirdClass 对象 = new MyThirdClass(arg1, arg2);
我可能会做一个
ComponentFactory myThirdClassFactory = myThirdClassServiceTracker.getService(); // 返回一个 if (myThirdClassFactory != null){ MyThirdClass 对象 = objectFactory.newInstance(); object.setArg1("arg1"); object.setArg2("arg2"); } 别的{ // 这里我可以假设 ComponentA 或 B 的某些服务消失了,因此无法创建 MyThirdClass 组件,因为缺少依赖项? }
在撰写本文时,我并不确切知道如何使用 ComponentFactories 但这应该是某种伪代码 :)
谢谢克里斯托夫