【发布时间】:2012-10-08 10:51:15
【问题描述】:
我正在设计一个应用程序,它的功能需要在不同的上下文中保持相同。参考下图:
+----+ +----+ +----+ |B1 +--->-----+B2 +-->----+B3 | |ctx1|使用 |ctx1|使用 |ctx1| +----+服务+----+服务+----+ +-------+ +----+ +----+ +----+ |上下文| |B1 +--->-----+B2 +-->----+B3 | |经理| |ctx2|使用 |ctx2|使用 |ctx2| | | +----+服务+----+服务+----+ | | : : : +-------+ : : : +----+ +----+ +----+ |B1 +--->-----+B2 +-->----+B3 | |ctxN|使用 |ctxN|使用 |ctxN| +----+服务+----+服务+----+有 4 个捆绑包:
- 上下文管理器
- B1
- B2
- B3
Context Manager 是负责了解新上下文何时可用并实例化 B1、B2 的新版本的包> 和 B3。 B2 和 B3 提供的服务在上下文中完全相同,只是我想在服务上添加一个属性以区分它在哪个上下文中运行(ctx1 vs ctxN for例子)。 现在这是我想要实现的理论,我认为我可以通过声明式服务轻松实现它,实际上我制作了 B1 *B2* 和 B3 是 ComponentFactory 通过在组件头中指定 component.factory 属性,我设置 B1 引用 B2 提供的服务strong>,我还设置了 B2 来引用 B3 提供的服务。 这些是我面临的挑战:
- Context Manager第一次了解到B3提供的ComponentFactory服务,只要B1和B2 还不满意,他们没有在服务注册表中注册 ComponentFactory 服务。只要是这种情况,B1 和 B2 就不会为第一个上下文实例化。
- B1 和 B2 一旦创建,从其他上下文获取任意服务,我正在考虑将 reference.target 参数设置为仅从同一上下文中选择服务,但它没有'似乎没有任何方法可以声明这样做,似乎从同一上下文中选择服务的唯一方法是通过设置基数 0..n 的引用并提供 “bind” 方法基于当前上下文进行选择,这意味着每个组件都必须复制相同的选择逻辑,而我认为可以由 上下文管理器 提供 newInstance叫做。事实上,如果在调用期间 ComponentFactory.newtInstance(props); 我可以提供像 .target=(context=mycontext) 这样的属性,那么这可以实现,但我不知道所有的参考组件实际上正在使用。
此时我正在考虑实际上避免使用声明式服务并让每个上下文包扩展一个我将提供的基类,该基类将基本上实现类似于 org.apache.felicy.dependencymanager 的依赖项跟踪,但这样每个上下文组件的开发人员不必担心知道代码位于哪个上下文中。但是我不想恢复到这个解决方案,我觉得我只是在复制逻辑可能已经存在于 OSGi 规范中,所以我的问题是:
在 OSGi 中创建可以在每个上下文基础上运行的包的最佳方法是什么,这样包可以以声明性方式描述依赖关系,而不必明确提及它们所在的上下文跑了吗?
【问题讨论】:
-
使用声明式服务应该没有问题。由于属性传播,您可以从配置中设置像
target这样的属性。 -
是的,可以提前知道我可以设置目标的参考,但这里的问题有两个:1)我需要首先发现工厂组件来实例化 2)我需要在组件中发现对服务的实例化引用。如果我解决了前两个问题,我可以从配置中设置目标属性。但我无法达到这一点。