实现企业集成模式 第0部分

工程 | Iwein Fuld | 2008年5月19日 | ...

在我关于Spring Integration的演讲之后,我收到了很多关于澄清和示例的问题。为了满足需求,我将开始一个小系列,介绍如何使用Spring Integration实现不同的集成模式。这第一篇文章将侧重于基础知识。它将向您展示如何启动和运行,并带您了解其中一个示例。

如果您以前从未听说过Spring Integration,那么阅读Mark Fisher撰写的介绍性博客或浏览项目网站,熟悉它可能是一个好主意。总的来说

让我先声明一下:……

Spring Web Flow 2 发布;引入新 Faces 和 JavaScript 模块

发布 | Keith Donald | 2008年5月15日 | ...

亲爱的Spring社区,

我们很高兴地宣布 Spring Web Flow 2 正式上市。 下载 | 文档

Spring Web Flow 是 Spring Portfolio 中专注于提供构建和运行富 Web 应用程序的基础设施的项目。作为 Spring 项目,Web Flow 基于 Spring Web MVC 框架提供:

  • 用于定义可重用控制器模块的特定领域语言,称为 flows
  • 用于管理对话状态的高级控制器引擎
  • 用于使用 Ajax 构建富用户界面的一流支持
  • 用于结合 Spring 使用 JavaServerFaces 的一流支持

Web Flow 2 发行版的模块及其与 Spring Framework 的关系如下所示:

Web Flow 2 的内容

Web Flow 2 Distribution Components

 

Spring Web MVC

Spring Web MVC 框架是 Spring Framework 发行版的模块,它使用经过验证的模型视图控制器(MVC)范例为使用 Spring 开发 Web 应用程序提供了基础。Web Flow 发行版的每个模块都建立在这个基础上。

Spring Web Flow

Web Flow 模块是 MVC 的扩展,允许您使用 特定领域语言 定义控制器。这种语言旨在模拟需要多次服务器请求才能完成的用户交互,或者可以从不同上下文调用。

Spring JavaScript

Spring JavaScript 是一个 JavaScript 抽象框架,可以轻松编写非侵入性 JavaScript,以逐步增强网页的行为。该框架包含一个公共 JavaScript API 以及一个基于 Dojo Toolkit 的实现。Spring.js 旨在简化常见企业场景中 Dojo 的使用,同时保留其在高级用例中的全部功能。

Spring JavaScript 可以与任何服务器端框架协同工作。Web Flow 2 发行版包括 Spring JavaScript 和 Spring Web MVC 之间方便的集成,用于处理 Ajax 请求。

Spring Faces

Spring Faces 模块包含 Spring 对 JavaServerFaces 的支持。这种支持允许您在熟悉的 Spring MVC 和 Web Flow Controller 环境中使用 JSF 作为视图技术。通过这种架构方法,您可以结合 JSF UI 组件模型的优势和 Web MVC 架构的优势。Spring Faces 还包含一个基于 Spring JavaScript 的轻量级组件库,用于以渐进的方式声明式地启用 Ajax 和客户端验证行为。

Web Flow 2 发行版的主题

除了引入新的 Spring Faces 和 Spring Javascript 模块外,Web Flow 2 发行版还解决了两个主要主题:集成和简洁性。

集成

在所有模块中,Web Flow 2 发行版都增加了许多有趣的集成,让您可以丰富您的 Web 应用程序。这些集成支持:

  • 使用 Spring Security 以声明式的方式保护您的 flows
  • 使用 Tiles 进行 JSP 页面组合和 Ajax 部分渲染
  • 在使用 JSF 时,使用 Facelets 进行页面组合和布局
  • 在使用 JSF 时,使用 Apache Trindad 和 JBoss RichFaces 组件库
  • 以渐进且非侵入性的方式使用 Dojo 部件系统;如果客户端没有 JavaScript,则会优雅降级。

简洁性

Web Flow 2 中的 flow 定义语言得到了极大的简化,同时整体功能也更加强大。这些简化包括:

  • 与版本 1 的 flow 定义相比,版本 2 的 flow 定义的代码行数总体减少了约 50%(示例:版本 2 对比 版本 1
  • 使用表达式语言(EL)调用操作的简洁语法,支持 Unified EL 和 OGNL
  • 声明式的模型绑定和验证,支持约定优于配置
  • 通过 flow 定义继承,在 flow 和 state 级别上支持重用
  • 增强的模块化,允许将 flow 及其依赖资源打包成一个独立的单元

发布说明

  • Web Flow 2 需要 Java 1.4 或更高版本,并在所有主流 Java EE 平台(包括 Tomcat、Jetty、Websphere、WebLogic 和 JBoss)上运行。
  • Web Flow 2 需要 Spring Framework 2.5.4 或更高版本。
  • Web Flow 2 已获得 SpringSource 的“Platform Ready”认证,适合在 OSGi 启用的 Web 应用程序中运行于 SpringSource dm Server

入门

其他社区资源

  • 阅读 SpringSource 的 Keith Donald 和 Jeremy Grelle 的 访谈,详细了解 Web Flow 2 发行版的新特性。
  • 观看 Ajaxian.com 的 访谈,其中与 Dion Almaer 讨论了发行版和 Spring JavaScript。
  • 在线探索 Spring Web 参考应用程序。 Spring Travel 应用程序展示了集成的 Web Flow 2 功能集,并包含在发行版中。 SpringSource Enterprise Bundle Repository 是一个基于 Spring 2.5 和 Spring Web Flow 2.0 构建的生产环境中的实际应用程序。
  • 如果您是现有的 Web Flow 1 用户,请查阅 迁移指南 以帮助您升级到 Web Flow 2。WebFlowUpgrader 工具可以自动将您的 flows 转换为版本 2 语法。
  • 通过 Fisheye 跟踪 Web Flow 源代码仓库的更新。
  • 通过 订阅 springframework.org 以获取有关 Web Flow 2 的未来文章。

我为什么要关心 OSGi?

工程 | Adrian Colyer | 2008年5月15日 | ...

InfoQ 有一个 讨论帖 总结了对 SpringSource 应用平台发布公告的反应。Michael Burke 在该帖中提出了一个 很棒的问题,可以这样转述:“抛开围绕 OSGi 的炒作,如果我将目前打包为 EAR 的应用程序移植到 OSGi bundles,我能期望看到什么好处?”

我开始在 InfoQ 帖子中回答这个问题,但我的答案对于评论来说太长了,所以我将在这里解决。

这个问题问得很好。基于 OSGi 的应用程序与传统的基于 JEE EAR 的应用程序之间的主要区别在于模块化得到了改进。所以问题变成了,这种改进的模块化是否给我带来了任何好处,如果带来了,它们是什么?《设计规则,模块化的力量》一书对这个问题进行了非常详尽的论述。它提供了很好的背景知识,但我感觉 Michael 可能正在寻找一些比那本书中更不理论化的东西……

使用 SpringSource Application Platform 的供应存储库

工程 | Andy Wilkinson | 2008 年 5 月 9 日 | ...

SpringSource Application Platform 的主要优势之一是其按需供应依赖项的能力。这有两个好处:它确保平台内存占用尽可能小,并且允许应用程序在不将所有依赖项封装在单一部署单元(例如 WAR 文件)中的情况下进行部署。要利用这些功能,您需要了解平台的供应存储库,而这篇博文将提供这些信息。

供应存储库在哪里?它是如何工作的?

默认情况下,平台的供应存储库位于安装根目录下的 repository 目录中:供应存储库的目录结构 如您所见,有三个主要目录:bundlesinstalledlibrariesinstalled 用于平台内部使用,所以我们将重点关注 bundleslibraries 目录。每个目录包含多个子目录,用于分隔不同类型的依赖项。
  • ext 包含平台提供的外部依赖项,但它们本身并非平台的一部分。
  • subsystems 包含构成平台的所有子系统。
  • usr 最初为空,用于包含用户添加的依赖项,即您的应用程序依赖但平台尚未提供的任何内容。
平台在启动时搜索 repository 目录结构中的捆绑包和库。我将在本文后面讨论如何配置此搜索。当在存储库中找到捆绑包和库时,它们的符号名称、导出包等详细信息将被添加到存储库的内存索引中。扫描完成后,内存索引将被缓存到磁盘。在开发过程中,最小化平台的启动时间是我们的一个重点。这种缓存允许平台在启动时节省一些时间:除非检测到存储库内容已更改,否则它可以跳过扫描。

运行时供应

在纯粹的 OSGi 环境中,捆绑包的依赖项只能由已安装在环境中的其他捆绑包来满足。例如,安装和启动一个导入 org.apache.commons.dbcp 包的捆绑包,如果还没有任何导出该包的捆绑包被安装,将会失败。这对于用户来说可能非常麻烦,因为他们必须手动安装捆绑包的所有依赖项。幸运的是,SpringSource Application Platform 通过按需动态安装依赖项,大大改进了这一点。

当平台启动已部署的应用程序时,其...

可移植性、炸鱼薯条

工程 | Rod Johnson | 2008 年 5 月 9 日 | ...

在 JavaOne 会议期间,在线上和线下,关于 SpringSource Application Platform 的讨论非常多。WebSphere 事务架构师 Ian Robinson 的一个最有见地的 评论 之一是:

这一切会影响 WebSphere 吗?嗯,Spring 核心框架本身没有任何变化。无论 SpringSource Application Platform 的未来如何,Spring 核心框架项目仍然可以与 WebSphere 互补。就像炸鱼薯条一样。
Ian 说得完全正确。SpringSource Application Platform 是 Spring 部署的另一个选择。没有什么改变...

SpringSource Application Platform Manifest 头部

工程 | Glyn Normington | 2008 年 5 月 8 日 | ...

SpringSource Application Platform 由 OSGi 捆绑包构建而成,并支持同样由 OSGi 捆绑包构建的应用程序。平台支持 OSGi 的标准功能,但也支持一些额外的清单头部。许多人曾问:“为什么 SpringSource 要添加专有头部?”以及“新头部有什么含义?”,因此本文解释了背景动机以及 Import-LibraryImport-Bundle 的含义。

标准 OSGi 捆绑包支持

平台基于 OSGi R4.1 标准,或者如果您更喜欢,可以认为是 JSR 291,并使用 Equinox 作为其 OSGi 实现。结果是,您可以使用平台的工具开发标准的 OSGi 捆绑包,并将这些捆绑包部署到平台,正如许多用户自平台发布以来一直在做的那样。

因此,熟悉 OSGi 的开发者可以将平台用作标准的 OSGi 容器,并受益于平台的功能,例如:

  • 通过管理控制台或将捆绑包放入平台的 pickup 目录来部署捆绑包的能力;
  • 诊断功能,如解析失败诊断、应用程序特定跟踪和自动死锁检测;
  • 与 Spring 和 Spring Dynamic Modules 的强大集成,适用于希望使用这些框架的开发人员;以及
  • 从存储库自动供应依赖项。
然而,平台还旨在让接触 OSGi 很少或没有经验的企业应用程序开发人员能够轻松受益于 OSGi,这给平台带来了一些额外的要求。

企业应用程序的其他要求

正如 Sam 最近关于平台部署选项的 博客 所解释的,您可以将现有的单体 WAR 文件部署到平台上,而无需了解 OSGi - 平台会为您处理一切。但是,要从共享库、共享服务以及最终的 PAR 文件范围中受益,就需要将单体 WAR 文件分解为 OSGi 捆绑包。这有多难?

好吧,过程中的一些步骤相对容易,特别是如果遵循了良好的软件工程实践并且代码已被组织成服务、域和基础设施组件。这些组件可以转换为捆绑包,它们之间的依赖关系可以使用 META-INF/MANIFEST.MF 中的标准 OSGi Import-Package 和 Export-Package 头部来表达。

一个更困难的步骤是表达对 Spring 和 Hibernate 等企业框架的依赖。使用标准的 OSGi Import-Package 和 Require-Bundle 头部来表达这些依赖关系是完全可能的,如果您想创建将在其他 OSGi 容器中运行的 OSGi 捆绑包,那么您应该这样做,但这种方法有一些隐藏的成本。

首先,开发人员必须精确地确定构成给定框架的包。仅仅导入应用程序代码使用的包是不够的,因为许多企业框架在应用程序加载时会在应用程序的字节码中注入进一步的依赖关系。开发人员必须通过试错来发现需要导入哪些额外的实现包,以确保编织后的应用程序能够正确运行。

然后是迁移到框架的新版本的工作,其中构成框架的包的精确集已发生更改。编织所需的附加包通常不是由公共契约定义的,因此可能会发生更改。

此外,生成的包导入未能正确捕获设计意图,这使得将来维护或扩展应用程序更加困难。

我们真的不想给用户带来这些负担,因此我们创建了一些额外的 SpringSource Application Platform 特定清单头部,Import-LibraryImport-Bundle,作为表达对企业框架依赖关系的便捷方式。正如您将在下面看到的,这些头部只是“语法糖”,它们本身就是标准的 OSGi 包导入。

Import-Library

基本语法与其他清单头部类似:
    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>,并省略分号分隔符,则默认范围包含所有版本。

对于每个库导入,平台会选择具有给定符号名称和给定版本范围内的最高版本库。然后,平台会将库导入替换为一组包导入,这些包导入匹配该库捆绑包导出的所有包。平台会检测到捆绑包导入两个或多个导出公共包的库的情况,会发出适当的日志消息,并阻止导入捆绑包的安装。

因此,例如,以下头部导入了介于 2.5.4(含)和 2.5.5(不含)之间的某个版本的 Spring Framework 库

    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 清单头部中指定一个逗号分隔的库导入列表,如下例所示:
    Import-Library: org.foo.p;version="[1,2)",org.bar.q;version="[2,3)"

Import-Bundle

Import-Bundle 是一个额外的便利功能,适用于库仅由一个捆绑包组成且创建库定义不便的情况。语法非常类似于 Import-Library,只是它引用的是捆绑包的符号名称和版本,而不是库的。

正如您所期望的,对于每个导入的捆绑包,平台会选择具有给定符号名称和给定版本范围内的最高版本捆绑包。然后,平台会将捆绑包导入替换为一组包导入,这些包导入匹配该捆绑包导出的包。

因此,例如,以下头部导入了 Hibernate 对象关系映射 捆绑包。

    Import-Bundle: com.springsource.org.hibernate;version="[3.2.6,3.2.7)"

为什么不重载 Require-Bundle

如果您熟悉 OSGi,您可能会问自己,为什么我们不重载 Require-Bundle 而引入 Import-Bundle

嗯,我们希望 Require-Bundle 保留其标准语义,包括将拆分的包组合在一起的能力。但我们希望 Import-LibraryImport-Bundle 具有与 Import-Package 相同的底层语义,从而避免拆分包的复杂性。

我们还预计,随着平台随时间的推移而发展,我们将需要向 Import-LibraryImport-Bundle 添加进一步的指令,这些指令不适合添加到 Require-Bundle

下一步是什么?

平台 beta 计划 正在进行中,我们将听取所有关于平台功能(包括新的清单头部)的反馈。

对于希望利用平台头部但需要生成可在其他 OSGi 容器上运行的捆绑包的用户,我们计划开发一个工具来替换 Import-LibraryImport-Bundle...

SpringSource 应用平台部署选项

工程 | Sam Brannen | 2008 年 5 月 6 日 | ...

自上周三发布 SpringSource 应用平台以来,众多开发人员下载了 1.0.0 测试版并开始试用该平台。结果,人们开始询问:“如何在平台上部署我的应用程序?我有哪些部署和打包选项?”此外,开发人员迫切希望看到可用的示例。作为回应,S2AP 团队将在未来几周发布几个示例应用程序,演示这些功能以及更多内容,但在您拿到这些示例之前,我想先给您一个高层次的…

Spring Web Services 1.5.1 发布

发布 | Arjen Poutsma | 2008年5月4日 | ...

亲爱的 Spring 社区:

我很高兴地宣布 Spring Web Services 1.5.1 已经发布!

下载 | 站点 | 更新日志 | 公告

这是 Spring-WS 1.5 系列的第一个错误修复和增强版本。它修复了自 1.5.0 以来报告的所有错误,并引入了框架中的各种增强功能

  • 引入了使用 OXM 编组器的 Spring JMS MessageConverter
  • 引入了使用 OXM 编组器的 Spring MVC View
  • 修复了结合 WSS4J 和 SAAJ 消息使用时的 WS-Security 签名问题
  • 支持 HTTP 传输的超时
  • 支持 Castor 1.2,请参阅下面的注释
  • Airline 示例现在使用 Spring Security

等等。请参阅更新日志了解详情。

请注意,由于向后兼容性问题,CastorMarshaller 现在需要 Castor 1.2 或更高版本。

干杯,

Arjen Poutsma
Spring Web Services 负责人

在 OSGi 上使用 SpringSource Application Platform 运行 Spring 应用程序

工程 | Rob Harrop | 2008 年 5 月 2 日 | ...

很多人一直在问 SpringSource Application Platform 究竟能为 Spring 应用程序做什么,使其在 OSGi 上运行良好,这超出了 OSGi 和 Spring Dynamic Modules 开箱即用的功能。Adrian 昨天的帖子重点介绍了一些一般性问题,现在我们来看一些细节。

在 OSGi 上运行 Spring 应用程序面临的三个最具挑战性的方面是

  • 加载时编织
  • 类路径扫描
  • 线程上下文类加载器管理

其余但不太有趣的方面包括:JSP 支持、TLD 扫描、注解匹配和资源查找。总而言之,有一些相当多的问题需要解决才能使应用程序平稳部署。

加载时编织

加载时编织是支持的一项最棘手的功能。在基本层面上,它需要挂钩到 Equinox 的 ClassLoader,以便在 defineClass 调用期间可以附加和使用标准的 ClassFileTransformers。在此基础上,许多 LTW 的用法需要访问一个一次性的 ClassLoader,该 ClassLoader 可用于检查类型以决定在编织期间需要做什么,而不会影响实际的 ClassLoader

这个基本级别的支持实际上是相当容易实现的。困难之处在于,当编织由一个 bundle 中的类驱动,但另一个 bundle 中的类需要被编织时。这在企业应用程序中很常见,其中一个 bundle 包含领域实体,另一个 bundle 包含使用 JPA EntityManager 的类型。Platform 通过确保应用程序中的所有 bundle 都可以使用适当的 ClassFileTransformers 进行编织来处理这种复杂性。

当您开始将编织传播到其他 bundle 时,您确实需要知道何时停止。如果您只是将编织应用于所有 bundle,那么应用程序将会相互干扰。Platform 通过显式地限定编织范围,使其仅应用于应用程序中的模块,从而防止这种情况发生。

LTW 的另一个问题是它会使刷新复杂化。当一个 bundle 被刷新时,OSGi 将刷新所有依赖于它的 bundle。这意味着,在我上面给出的例子中,刷新领域 bundle 会导致 EntityManager bundle 被刷新。然而,刷新 EntityManager **不会**刷新领域 bundle,这意味着编织可能不同步。Platform 通过将刷新传播到受编织影响的其他 bundle 来处理此问题。

类路径扫描

对于类路径扫描,主要问题是 Equinox 不暴露标准的 jar:file: 资源。Platform 在中间放置了一个适配器,以便库可以看到它们期望的资源协议。这有一个很好的副作用,就是使**大量**第三方库能够工作——这不仅仅是类路径扫描的修复。

线程上下文类加载器管理

许多第三方库使用线程上下文 ClassLoader 来访问应用程序类型和资源。OSGi 中的每个 bundle 都有自己的 ClassLoader,因此,在任何时候只能公开一个 bundle 作为线程上下文 ClassLoader。这意味着,如果第三方库需要查看分布在多个 bundle 中的类型,它将无法按预期工作。

Platform 通过创建一个 ClassLoader 来解决这个问题,该 ClassLoader 导入您应用程序中每个模块的所有导出的包。然后,此 ClassLoader 作为线程上下文 ClassLoader 公开,使第三方库能够看到您应用程序中的所有导出类型。

这只是 Platform 所解决问题的一小部分,但希望它能让您对 Platform 对 Spring Framework 用户意味着什么有所了解。

获取 Spring 新闻通讯

通过 Spring 新闻通讯保持联系

订阅

领先一步

VMware 提供培训和认证,助您加速进步。

了解更多

获得支持

Tanzu Spring 提供 OpenJDK™、Spring 和 Apache Tomcat® 的支持和二进制文件,只需一份简单的订阅。

了解更多

即将举行的活动

查看 Spring 社区所有即将举行的活动。

查看所有