领先一步
VMware 提供培训和认证,助力您的进步。
了解更多** 5 月 2 日更新了案例研究:- 详情请参见本文底部 ** 我相信大多数阅读此博客的人都已看到昨天 SpringSource 应用平台的发布公告。如果还没有,请务必查看 Rob 的博客文章,其中描述了一些动机、编程模型和路线图。
有两个常见问题我希望在此篇文章中立即解答。之后,我将描述另外两个令人兴奋的公告,它们与 SpringSource 应用平台本身相辅相成,但昨天并未占据头条:SpringSource 企业 Bundle 仓库和用于 Eclipse 的应用平台工具。它们共同完善了围绕基于 OSGi 的企业应用开发与 Spring 的整个故事。
过去 24 小时内我多次听到的问题是:OSGi 有什么问题 - 为什么我们不能直接使用纯净的 OSGi 服务平台(例如 Equinox、Felix 或 Knopflerfish),而非 SpringSource 应用平台?
OSGi 绝对没有任何问题。
OSGi 是一个出色的基础和服务平台 - 这也是我们和许多其他方选择在其基础上构建的原因。它已在广泛的行业和应用中得到验证,并且支撑着像 Eclipse 和 IBM 的 WebSphere 等应用,以及其他几家供应商的中间件栈。
直接使用 OSGi 规范 API 进行编程缺乏一些我们对企业应用所期望的特质 - 例如使用依赖注入的能力以及在容器外部轻松进行单元和集成测试的应用创建能力。直接使用 OSGi 规范 API 进行编程还迫使您在相对较低的层级处理 OSGi 平台的动态性 - 当您依赖的模块和服务在运行时停止、启动、安装和更新时,您会怎么做?但这里没有根本性的障碍,我们无法通过 Spring Dynamic Modules 项目克服这些障碍。使用 Spring Dynamic Modules 构建的应用可以在任何标准的 OSGi 服务平台上运行,并且我们针对 Equinox、Felix 和 Knopflerfish 测试了所有构建。我们致力于确保 Spring Dynamic Modules 和基于 Spring 的编程模型保持运行时中立。这个立场不会因为 SpringSource 应用平台的引入而改变。
现有的企业库也绝对没有任何问题。
嗯,好吧。确实有一些情况不尽如人意,但总体而言,我们知道如何让它们满足企业应用开发的需求。
那么问题出在哪里呢?
如果 OSGi 工作得很好,并且现有的企业库也满足我们的需求,那么问题出在哪里?困难在于尝试将 OSGi 服务平台与一组未考虑 OSGi 而编写的现有企业库结合时。这不是 OSGi 的错,它拥有一个出色的模型,提供了卓越的模块化、版本控制和操作控制。也不是企业库的错 - 它们并不是为在 OSGi 下运行而编写的。但正是那些让 OSGi 如此吸引人的特性打破了那些企业库开发者所做的假设。例如,OSGi 的模块化模型阻止你查看其他 Bundle 的私有部分。这正是你想要的,直到你意识到你的企业库无法再看到你的应用类型。许多东西都可能崩溃:从 commons logging 到 jsps,从标签库到数据源,从加载时织入到组件扫描,从资源加载到 orm 映射。不胜枚举……(是的,当你将应用代码和它所需的所有库打包到一个 Bundle 中时,你可以让这些东西中的许多工作,但这很大程度上偏离了重点!)。
这就是为什么你会看到许多人在 OSGi 之上构建,但很少将 OSGi 的好处传递到应用编程模型中(Eclipse RCP 是一个罕见的例外)。当你在 OSGi 之上构建,但不一定将该模型暴露给终端用户应用开发时,你可以按照 OSGi 模型构建并使其工作。当你需要提供一个平台,在该平台上可以使用大量的现有企业库时,情况就不同了。如果我们能抛弃所有这些,从头开始使用专门为 OSGi 编写的库,我们会没问题。例如,我们确保了 Spring Framework 完全能够在 OSGi 服务平台内部运行。但这并非现实可行的提案。或者,我们可以等待现有库的开发者将它们全部转换以在 OSGi 下开箱即用(就像我们对 Spring 所做的那样)。但除非其他人都这么做,否则他们这样做的动机是什么?所以我们似乎陷入了先有鸡还是先有蛋的困境。这是 OSGi 企业专家组在过去一年中花费大量时间讨论的问题。SpringSource 应用平台解决的正是这个问题:- 通过使具有标准 OSGi 语义的标准 OSGi Bundle 与现有企业应用库协同工作,从而将企业应用开发引导到 OSGi 的世界中。
我还要再次强调,该平台不仅仅是关于 OSGi:OSGi 支持是我们最兴奋的特性之一,但 SpringSource 应用平台也是一个出色的服务器平台,用于部署标准的 war 文件。我们将在后续文章中描述该平台在这种场景下提供的优势。
希望这篇文章有助于澄清围绕 SpringSource 应用平台与 OSGi 之间关系的困惑。如果您一直关注到这里,可能已经注意到了另一个潜在的问题:让现有企业库在 OSGi 下工作固然不错,但您是否需要将它们所有的 jar 文件都转换为 OSGi Bundle 才能部署它们呢?是的,您需要。事实证明,如果您想正确地对所有导入和导出进行版本控制并确保具有正确的符号名称等,这将是一项大量的工作。好消息是,对于数百个常用的企业应用库,我们已经为您完成了艰苦的工作,并在 SpringSource 企业 Bundle 仓库中提供了 OSGi 就绪的版本...
摘自常见问题解答
"SpringSource 企业 Bundle 仓库是使用 Spring Framework 开发企业 Java 应用常用的开源库集合。仓库包含 jar 文件 (Bundle) 和库定义 (".libd") 文件。库定义了一组 Bundle,这些 Bundle 通常会为了某个目的(例如 "Spring Framework" 库)一起使用。仓库中包含数百个 Bundle。" 该仓库满足以下条件:
Eclipse 已经内置了 OSGi 开发工具。由于每个 Eclipse 插件也是一个 OSGi Bundle,因此 Eclipse PDE 工具(插件开发环境工具)可以用于 OSGi 应用开发。然而,这些工具主要设计用于开发 Eclipse 插件这一事实显而易见,在使用它们进行 OSGi 应用开发时存在一些常见的令人沮丧的地方。一个问题是 META-INF/MANIFEST.MF 文件只能放在项目的根目录下 - 这与 Ivy 和 Maven 等构建工具配合得不好;另一个问题是您整个工作空间只能受限于一个目标平台(用于开发的 Bundle 集合)。PDE 工具真正出色的地方,也是您真正需要的,是它们从 OSGi manifest 构建项目的编译类路径 - 这样在编译、测试和运行时之间就不会出现类路径和类可见性的差异。
与 SpringSource 应用平台一起,我们还发布了一套 Eclipse 插件(可从 SpringSource 应用平台下载页面获取),这些插件使得 OSGi 应用的开发更加容易,特别是针对 SpringSource 应用平台的应用。您的 META-INF/MANIFEST.MF 文件可以位于任何源目录中,并且这些工具从 manifest 条目构建编译类路径。然而,您可以将您的项目与定义到 Eclipse 的 SpringSource 应用平台服务器关联(使用 WTP 功能),而不是单个目标平台。然后,您项目的类路径将从您 manifest 文件中的导入语句派生,针对您工作空间中的其他 Bundle 项目以及关联服务器中安装的 Bundle 进行解析。您在编译时获得的类路径和依赖项的解释与您在运行时获得的完全相同。当然,正常的“部署到服务器”选项也有效。
这是服务器在 Eclipse 内部运行时的情况:
此截图显示了如何使用“Bundle Dependencies”类路径容器管理类路径。请注意,您未在 manifest 文件中导入的包被灰显,表示您当前无法访问它们。
更好的是我们如何能够利用 OSGi 的模块化。一组项目(每个 Bundle 一个)构成了您的应用。当您更改项目中的任何内容时,额外的增量构建器会分析资源差异,并对 SpringSource 应用平台中正在运行的 Bundle 进行实时更新 - 因此您始终运行的是最新代码:每一次,始终如此。这极大地提高了生产力,并提供了出色的开发体验。
com.springsource.platform.deployer.core.DeploymentException: Unable to satisfy constraints of 'myapp' version '0.0.0':
Cannot resolve: myapp Unsatisfied leaf constraints:
Bundle: myapp_0.0.0 - Import-Package: org.springframework.osgi.web.context.support; version="0.0.0"
Did you mean: 'org.springframework.osgi.context.support'?
Bundle: myapp_0.0.0 - Import-Package: freemarker.ext.servlet; version="0.0.0"
Did you mean: 'javax.servlet'?
Bundle: myapp_0.0.0 - Import-Package: freemarker.core; version="0.0.0"
Did you mean: 'org.hamcrest.core'?
Bundle: myapp_0.0.0 - Import-Package: freemarker.template; version="0.0.0"
Did you mean: 'org.antlr.tool'?
Bundle: myapp_0.0.0 - Import-Package: freemarker.cache; version="0.0.0"
Did you mean: 'org.apache'?这些是预期的消息,因为我没有在平台中安装 freemarker 或 osgi.web.context 支持 Bundle。
Import-Package: javax.servlet,javax.servlet.http,javax.servlet.resources,javax.swing.tree,
javax.naming,org.w3c.dom,org.apache.commons.logging,javax.xml.parsers;resolution:=optional,
org.xml.sax;resolution:=optional,org.xml.sax.helpers;resolution:=optional,
org.springframework.osgi.web.context.support, org.springframework.context.support,
org.springframework.web.context, org.springframework.web.context.support,
org.springframework.web.servlet, org.springframework.web.servlet.mvc,
org.springframework.web.servlet.mvc.support, org.springframework.web.servlet.view,
org.springframework.ui, org.springframework.web.servlet.view.
freemarker, freemarker.cache,freemarker.core,freemarker.template,freemarker.ext.servlet我将其简化为:
Import-Package: org.apache.commons.logging
Import-Library: org.springframework.spring;version="[2.5.4,3.0.0)"
Import-Bundle: com.springsource.freemarker;version="2.3.12"当我们知道您正在部署 Web 应用时,常用的导入会在部署时自动添加。Import-Library 和 Import-Bundle 让您可以方便地在单个语句中引用库和 Bundle。我还删除了“Bundle-Classpath”条目,因为应用平台会自动检测 WEB-INF/lib 中的库并将其添加到 Bundle 类路径中。