OSGI捆绑包和组件有什么区别?

2022-09-04 20:31:15

开始使用osgi,我想知道捆绑包和组件之间的概念差异是什么。以及何时使用它们中的哪一个。欢迎任何指点。

编辑:

组件和捆绑包提供不同的接口,因此它们可能无法互换


答案 1

组件是:

  • 系统中的积极参与者
  • 了解并适应其环境
    • 环境 = 其他组件提供的服务
    • 环境 = 资源、设备...
  • 可能向其他组件提供服务并使用其他组件的服务
  • 具有生命周期

总之:

  • 组件提供服务
  • 捆绑包管理生命周期

一个捆绑包只能有一个激活剂(需要一个 ),并且可以有任意数量的活动组件。
这意味着您最终可能会尝试将几个松散相关的问题放入一个类中。
这就是为什么通过 SCR(“服务组件运行时”,它是实现新的和改进的 OSGi R4.2 DS - 声明性服务 - 规范的“扩展器捆绑包”)来管理这些组件的原因。
自OSGi 4.2以来尤其如此,因为现在将DS组件编写为POJO要容易得多:和方法不再需要采用参数。另请参见惰性声明性服务BundleContextactivatedeactivateComponentContext


注意:

它可以帮助在OSGi的上下文中替换这些术语,并查看“我们如何到达那里”(Neil Bartlett的优秀博客文章))

以下是一些相关的摘录,其中“模块”最终是OSGi捆绑包(管理声明服务的组件):

模块分离

我们的第一个要求是干净地分离模块,以便来自一个模块的类不具有不受控制地查看和隐藏来自其他模块的类的能力
在传统的Java中,所谓的“classpath”是一个巨大的类列表,如果多个类碰巧具有相同的完全限定名称,那么第一个类将始终被找到,第二个和所有其他类将被忽略。

防止不受控制的可见性和类模糊的方法是为每个模块创建一个类装入器。类装入器只能直接装入它所知道的类,在我们的系统中,这将是单个模块的内容。

模块访问级别

如果我们止步于此,那么模块将完全隔离,无法相互通信。为了使系统实用,我们需要重新添加查看其他模块中的类的能力,但我们以谨慎和受限制的方式进行。
在这一点上,我们输入了另一个要求:模块希望能够隐藏它们的一些实现细节。

我们希望有一个“模块”访问级别,但今天的问题是javac编译器不知道模块边界在哪里。

我们在模块系统中选择的解决方案是允许模块仅“导出”其部分内容。如果模块的某些部分未导出,则其他模块根本看不到它。

在导入时,我们应该导入我们实际需要使用的东西,无论它来自哪里,而忽略所有碰巧与它一起包装的东西。

进出口的粒度

OSGi 选择软件包。
Java包的内容旨在保持某种程度的一致性,但是将包列为导入和导出并不太繁琐,并且将某些包放在一个模块中而将其他包放在另一个模块中不会破坏任何内容。
应该位于模块内部的代码可以放在一个或多个未导出的包中。

封装布线

现在我们已经有了一个模块如何隔离自己然后重新连接的模型,我们可以想象构建一个框架来构建这些模块的具体运行时实例。它将负责安装模块并构建了解其各自模块内容的类装入器。

然后,它将查看新安装的模块的导入,并尝试找到匹配的导出。

一个意想不到的好处是我们可以动态安装,更新和卸载模块。安装新模块对那些已解决的模块没有影响,尽管它可能会使一些以前无法解析的模块得到解决。卸载或更新时,框架确切地知道哪些模块受到影响,如有必要,它将更改其状态。

版本

我们的模块系统看起来不错,但我们还无法处理模块中随时间推移不可避免地发生的变化。我们需要支持版本。

我们是怎么做到的?首先,导出者可以简单地声明有关其导出的包的一些有用信息:“这是API的1.0.0版本”。导入者现在只能导入与其预期内容兼容且已编译/测试的版本,并拒绝接受

打包模块和元数据

我们的模块系统需要一种方法将模块的内容与描述导入和导出的元数据打包到一个可部署的单元中。

因此,唯一的问题是,我们应该将元数据放在哪里,即导入和导出列表,版本等?

碰巧OSGi是在2000年之前设计的,所以它确实选择了这两种解决方案中的任何一种。相反,它回顾了JAR文件规范,其中拼写出了答案:
是任意特定于应用程序的元数据的标准位置。META-INF/MANIFEST.MF

后期绑定

模块化难题的最后一块是实现到接口的后期绑定。我认为这是模块化的一个关键特征,即使一些模块系统完全忽略了它,或者至少认为它超出了范围。

我们应该寻找一种分散的方法
与其让 God 类告诉他们该怎么做,不如假设每个模块都可以简单地创建对象,并将它们发布到其他模块可以找到它们的地方。我们将这些已发布的对象称为“服务”,将它们发布的位置称为“服务注册表”。
有关服务的最重要信息是它实现的接口(或多个接口),因此我们可以将其用作主注册密钥。
现在,需要查找特定接口实例的模块可以简单地查询注册表并找出当时可用的服务。注册表本身仍然是存在于任何模块之外的核心组件,但它不是“上帝”......相反,它就像一个共享的白板。


答案 2

在OSGi术语中,“组件”就像一个运行时服务。每个组件都有一个实现类,并且可以选择实现一个公共接口,从而有效地提供此“服务”。OSGi 的这一方面有时被比作服务注册表模式。

根据定义,OSGi 中的组件由捆绑包提供。捆绑包可能包含/提供多个组件。虽然捆绑包本身可能不提供服务,但组件/声明性服务用于使OSGi更加面向服务。您没有义务使用组件/服务。


推荐