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