OSGi中的每上下文服务



我正在设计一个应用程序,它的功能在不同的上下文中需要相同。请参阅下图:

+-----++----++----+|B1+-->-----+B2+-->----+B3||ctx1|use|ctx1|use |ctx1|+----+服务+----+服务+----++-------++-----++----++----+|上下文||B1+--->-----+B2+-->----+B3||经理||ctx2|use|ctx2| use|ctx2|||+-----+服务+----+服务+----+||:::+-------+:::+----++----++----+|B1+-->-----+B2+-->----+B3||ctxN|use|ctxN|使用|ctxN|+----+service+----+service+----+

有4个捆绑包:

  • 上下文管理器
  • B1
  • B2
  • B3

上下文管理器是负责了解新上下文何时可用并实例化B1B2B3的新版本的捆绑包。B2B3提供的服务在不同的上下文中完全相同,只是我想在服务上添加一个属性,以区分它在哪个上下文中运行(例如ctx1和ctxN)。现在这就是我想要实现的理论,我认为我可以通过声明服务轻松实现它,事实上,我通过在组件头中指定component.factory属性,将B1*B2*和B3设置为ComponentFactory,并将B1设为引用B2提供的服务,我还将B2设置为指代B3提供的服务。这些是我面临的挑战:

  • Context Manager了解到只有B3提供的ComponentFactory服务,第一次,只要B1B2还不满意,他们就不会在服务注册表中注册Component Factory服务。只要是这种情况B1B2就不会为第一个上下文实例化
  • B1B2一旦创建,就会从其他上下文中获取任意服务,我想设置reference.target参数,只从同一上下文中选择服务,但似乎没有任何方法可以声明性地做到这一点,似乎从同一上下文中选择服务的唯一方法是设置基数为0..n的引用,并提供一个基于当前上下文进行选择的"绑定">方法,这意味着每个组件都必须复制相同的选择逻辑,相反,我认为当调用newInstance时,上下文管理器可以提供该逻辑。事实上,如果在调用ComponentFactory.newtInstance(props)i可以提供像.target=(context=myntext)这样的属性,然后这就可以实现,但我不知道组件实际使用的所有引用

在这一点上,我想实际避免使用Declarative Service,并让每个上下文捆绑包扩展我将提供的基类,该基类将基本上实现类似于org.apache.filecy.dependencymanager的依赖性跟踪,但这样每个上下文组件的开发人员就不必担心知道代码位于哪个上下文中。然而,我不想回到这个解决方案,我觉得我只是在复制OSGi规范中可能已经存在的逻辑,所以我的问题是:

在OSGi中创建可以在每个上下文基础上运行的捆绑包的最佳方式是什么,这样捆绑包就可以以声明的方式描述依赖关系,而不必明确提及它们运行的上下文

这里有一些令人困惑的术语。您谈论的是束B1、B2和B3。您还讨论了实例化B1、B2和B3的新版本。你的意思是更新捆绑包B1、B2和B3吗?还是说捆绑包B1、B2和B3分别提供服务S1、S2和S3?

回答我自己的问题。只要我需要一个解决方案,在Apache Felix DependencyManager的帮助下,我就替换了Declarative Services,并为每个上下文bundle(下面源代码中的Container)创建了一个新的依赖管理器实例,它有助于在每个上下文的基础上跟踪服务。

有关代码参考,请查看:OpenDayLight ComponentActivatorAbstractBase

为了管理依赖项并确保它们在同一上下文中,创建了一个特殊的ServiceDependency,供参考:OpenDayLight ServiceDependency

关于如何实际使用激活器的示例,请参阅:OpenDayLight示例激活器

希望这对其他人也有用。

最新更新