抢先一步
VMware 提供培训和认证,助您快速提升。
了解更多SpringSource 应用平台由 OSGi 捆绑包构建而成,并支持同样由 OSGi 捆绑包构建的应用程序。该平台支持 OSGi 的标准功能,但也支持一些额外的清单文件头。许多人曾提出疑问:“为什么 SpringSource 添加了专有头文件?”以及“新头文件的语义是什么?”,因此本文解释了背后的动机以及Import-Library和Import-Bundle的语义。
因此,精通 OSGi 的开发人员可以使用该平台作为标准 OSGi 容器,并受益于平台的功能,例如:
嗯,此过程中的某些步骤相对容易,尤其是在遵循良好的软件工程实践并将代码组织成服务、域和基础设施组件的情况下。这些组件可以转换为捆绑包,并且它们之间的依赖关系可以使用标准 OSGi Import-Package 和 Export-Package 头文件在META-INF/MANIFEST.MF中表达。
一个更困难的步骤是表达对企业框架(如 Spring 和 Hibernate)的依赖。完全可以使用标准 OSGi Import-Package 和 Require-Bundle 头文件来表达这些依赖关系,如果您目标是创建将在其他 OSGi 容器中运行的 OSGi 捆绑包,那么这正是您应该做的,但这方法有一些隐含的成本。
首先,开发人员必须准确确定构成给定框架的包。仅仅导入应用程序代码使用的包是不够的,因为当应用程序加载时,一些企业框架会将更多依赖项编织到应用程序的字节码中。开发人员必须通过反复试验来发现还需要导入哪些额外的实现包,以确保编织后的应用程序行为正确。
然后是将框架从一个版本迁移到下一个版本的工作,其中构成框架的包的精确集合已经发生了变化。编织所需的额外包通常不由公共契约定义,因此可能会发生变化。
此外,生成的包导入没有正确捕捉设计意图,这使得将来维护或扩展应用程序更加困难。
我们真的不想给我们的用户带来这些负担,因此我们创建了一些额外的 SpringSource 应用平台特定的清单文件头,Import-Library和Import-Bundle,作为表达对企业框架依赖的便捷方法。正如您将在下面看到的,这些头文件实际上只是语法糖
,它们是用标准 OSGi 包导入来表达的。
Import-Library: <librarySymbolicName>;version=<versionRange>其中<librarySymbolicName>是库的
符号名称,而<versionRange>是使用 OSGi 版本范围表示法的库的可接受版本的范围。库定义指定了库的符号名称和版本,这两者一起唯一地标识了平台的库。
如果您不熟悉 OSGi 版本范围表示法,最常用的形式是最低版本范围,例如2
,表示版本 2 或更高版本
,以及半开
范围,例如[2.2.1,2.2.2)
,表示 2.2.1(包含)到 2.2.2(不包含)之间的任何版本。如果省略version=<versionRange>(当然也包括分号分隔符),则默认范围包括所有版本。
对于每个库导入,平台都会选择具有给定符号名称和给定版本范围内平台存储库中最高版本的库。然后,平台会将库导入替换为一组包导入,这些包导入与库的捆绑包导出的所有包匹配。平台会检测捆绑包导入两个或多个导出公共包的库的情况,发出相应的日志消息,并失败安装导入的捆绑包。
例如,以下头文件导入某个版本的Spring Framework 库,版本范围为 2.5.4(包含)到 2.5.5(不包含):
Import-Library: org.springframework.spring;version="[2.5.4,2.5.5)"
:=分隔符,它表示修改清单文件头语义的
指令,而不是
=分隔符,它表示
匹配属性,如version。
Import-Library: <librarySymbolicName>;version=<versionRange>;resolution:=optional
如果未指定resolution,或将其指定为mandatory,则如果不存在具有给定符号名称和给定范围内的版本的库,则包含导入库头文件的捆绑包将无法安装。但是,如果指定了resolution:=optional,则如果找不到合适的库,则将忽略库导入。
例如,以下头文件导入 2.5 及更高版本的 Spring Framework 库,但如果找不到合适的库,则会被忽略:
Import-Library: org.springframework.spring;version="2.5";resolution:=optional
Import-Library: org.foo.p;version="[1,2)",org.bar.q;version="[2,3)"
正如您所料,对于每个导入的捆绑包,平台都会选择具有给定符号名称和给定版本范围内平台存储库中最高版本的捆绑包。然后,平台会将捆绑包导入替换为一组与捆绑包导出的包匹配的包导入。
例如,以下头文件导入Hibernate 对象关系映射器捆绑包:
Import-Bundle: com.springsource.org.hibernate;version="[3.2.6,3.2.7)"
嗯,我们希望Require-Bundle保留其标准语义,包括能够将拆分包的各个部分结合在一起的能力。但是我们希望Import-Library和Import-Bundle具有与Import-Package相同的底层语义,从而避免拆分包的复杂性。
我们还预计,随着平台的不断发展,我们将需要向Import-Library和Import-Bundle添加更多指令,而这些指令不适合添加到Require-Bundle中。
对于希望利用平台头文件,但需要生成可在其他 OSGi 容器上运行的捆绑包的用户,我们计划开发一个工具,用等效的标准包导入来替换Import-Library和Import-Bundle语法糖。
我们还将与 OSGi 联盟的同事讨论新的清单头文件,以确定是否存在 OSGi 未来应解决的普遍需求。