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

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

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

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

让我先声明一下:...

Spring Web Flow 2 发布;引入了新的界面和 JavaScript 模块

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

尊敬的 Spring 社区:

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

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

  • 用于定义称为的可重用控制器模块的领域特定语言
  • 用于管理会话状态的高级控制器引擎
  • 使用 Ajax 构建富用户界面的第一类支持
  • 使用 JavaServerFaces 与 Spring 集成的第一类支持

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

Web Flow 2 中有什么

Web Flow 2 Distribution Components

 

Spring Web MVC

Spring Web MVC 框架(Spring Framework 发行版中的一个模块)为使用经过验证的 ModelViewController 范式使用 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 控制器环境中使用 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 保护您的流
  • 使用 Tiles 进行 JSP 页面组合和 Ajax 部分渲染
  • 使用 JSF 时,使用 Facelets 进行页面组合和布局
  • 使用 JSF 时,使用 Apache Trindad 和 JBoss RichFaces 组件库
  • 以渐进且不显眼的方式使用 Dojo 小部件系统;如果客户端上没有 JavaScript,则以优雅的方式降级

简洁性

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

  • 将版本 2 流定义与其版本 1 等效项进行比较时,代码行减少了大约 50%(例如:版本 2版本 1
  • 使用表达式语言 (EL) 调用操作的简洁语法,支持统一 EL 和 OGNL
  • 声明式模型绑定和验证,支持约定优于配置
  • 使用流定义继承在流和状态级别都支持重用
  • 增强的模块化,允许将流及其相关资源打包到一个自包含的包中

发行说明

  • 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 的“平台就绪”认证,适用于在支持 OSGi 的 Web 应用程序的SpringSource dm Server上运行。

入门

其他社区资源

  • 观看Ajaxian.com 访谈,其中与 Dion Almaer 讨论了发布和 Spring JavaScript。
  • 在线浏览 Spring Web 参考应用程序。Spring Travel应用程序展示了集成的 Web Flow 2 功能集,并包含在发行版中。SpringSource Enterprise Bundle 存储库是在 Spring 2.5 和 Spring Web Flow 2.0 上构建的生产中的真实世界应用程序。
  • 如果您是现有的 Web Flow 1 用户,请查看迁移指南以帮助升级到 Web Flow 2。WebFlowUpgrader 工具自动将您的流转换为版本 2 语法
  • 使用Fisheye跟踪 Web Flow 源代码存储库的更新
  • 通过订阅springframework.org 关注即将发布的关于 Web Flow 2 的文章

为什么我应该关心 OSGi?

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

InfoQ 有一个讨论主题,总结了对 SpringSource Application Plaform 发布的反应。Michael Burke 在该主题上提出了一个很好的问题,可以将其概括为“忘记围绕 OSGi 的炒作,如果我将当前打包为 EAR 的应用程序移植到 OSGi 捆绑包,我可以期望看到哪些好处?”

我开始在 InfoQ 主题上回答这个问题,但我的答案对于评论来说太长了,所以我将在本文中解决它。

这是一个很好的问题。在基于 OSGi 的应用程序与传统的基于 JEE EAR 的应用程序之间,您将看到的最大区别是模块化的改进。因此,问题就变成了,这种改进的模块化是否会给我带来任何好处,如果是,它们是什么?这本书“设计规则,模块化的力量”对这个问题进行了非常全面的论述。这是一个很好的背景,但我有一种感觉,迈克尔可能正在寻找一些比你在那本书中找到的东西更不那么理论化的东西……

使用 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 日 | ...

很高兴听到关于 SpringSource Application Platform 的大量讨论,无论是在线还是在 JavaOne 的现场。WebSphere 事务架构师 Ian Robinson 提供了最具洞察力的 评论 之一

这是否会影响 WebSphere?好吧,Spring 框架的核心没有任何变化。无论 SpringSource Application Platform 的未来如何,Spring 框架核心项目都将继续与 WebSphere 互补。就像炸鱼薯条一样。
Ian 完全正确。SpringSource Application Platform 是 Spring 部署的另一种选择。在…中没有任何变化。

SpringSource Application Platform 清单头

工程 | 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>(当然还有分号分隔符),则默认范围包括所有版本。

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

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

Import-Bundle

Import-Bundle 进一步方便了库仅包含单个捆绑包且创建库定义不方便的情况。语法与 Import-Library 非常相似,除了它引用捆绑包的符号名称和版本而不是库的符号名称和版本。

如您所料,对于每个导入的捆绑包,平台都会选择具有给定符号名称和平台存储库中提供的给定版本范围内的最高版本的捆绑包。然后,平台将捆绑包导入替换为一组包导入,这些导入与捆绑包导出的包匹配。

例如,以下标题导入 Hibernate Object-Relational Mapper 捆绑包

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

为什么不重载 Require-Bundle

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

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

我们还预计,随着平台的不断发展,我们将需要向 Import-LibraryImport-Bundle 添加更多指令,这些指令不适合添加到 Require-Bundle 中。

接下来是什么?

SpringSource 应用平台的 Beta 计划 正在进行中,我们将收集所有关于平台功能的反馈,包括新的清单头文件。

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

SpringSource 应用平台部署选项

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

自从我们上周三发布 SpringSource 应用平台以来,许多开发人员已经下载了 1.0.0 Beta 版,并开始试用该平台。因此,人们开始询问:“如何将我的应用程序部署到平台上,以及我有哪些部署和打包选项?” 此外,开发人员迫切希望看到工作示例。作为回应,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 消息转换器。
  • 引入了使用 OXM 编组器的 Spring MVC 视图。
  • 修复了在将 WSS4J 与 SAAJ 消息结合使用时,WS-Security 签名的问题。
  • 支持 HTTP 传输的超时。
  • 支持 Castor 1.2,请参阅下面的说明。
  • 航空公司示例现在使用 Spring Security。

以及更多。请参阅变更日志以了解详细信息。

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

此致,

Arjen Poutsma
Spring Web Services 负责人

在 OSGi 上使用 SpringSource 应用平台运行 Spring 应用程序

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

许多人一直在询问 SpringSource 应用平台究竟为 Spring 应用程序做了什么,才能使它们在 OSGi 下良好运行,以及除了 OSGi 和 Spring Dynamic Modules 开箱即用提供的功能之外,还提供了哪些功能。Adrian 昨天的帖子强调了一些一般问题,现在让我们看看一些细节。

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

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

其余不太重要的问题包括:JSP 支持、TLD 扫描、注释匹配和资源查找。总的来说,需要解决大量问题才能使应用程序顺利部署。

加载时织入

加载时织入是在健壮的方式下支持的最具问题性的功能之一。在基本层面上,它需要挂接到 Equinox 的 ClassLoader,以便可以在 defineClass 调用期间附加和使用标准的 ClassFileTransformers。最重要的是,LTW 的许多用法都需要访问一个一次性 ClassLoader,该加载器可用于检查类型以确定在织入过程中需要发生什么,而不会影响真实的 ClassLoader

实际上,这种基本级别的支持实现起来相当简单。困难在于,当织入由一个 Bundle 中的类驱动,但另一个 Bundle 中的类需要被织入时。这在企业应用程序中非常常见,其中一个 Bundle 包含域实体,另一个 Bundle 包含使用 JPA EntityManager 的类型。平台通过确保应用程序中的所有 Bundle 都可以使用相应的 ClassFileTransformers 进行织入来处理这种复杂性。

当您开始将织入传播到其他 Bundle 时,您确实需要知道何时停止。如果您只是将织入应用于所有 Bundle,那么应用程序将相互干扰。平台通过显式地对织入进行范围限定来防止这种情况发生,以便它仅应用于应用程序中的模块。

LTW 的另一个问题是它使刷新变得复杂。当一个 Bundle 刷新时,OSGi 将刷新所有依赖它的 Bundle。这意味着,在我上面给出的示例中,刷新域 Bundle 将导致 EntityManager Bundle 刷新。但是,刷新 EntityManager **不会**刷新域 Bundle,这意味着织入可能不同步。平台通过将刷新传播到受织入影响的其他 Bundle 来处理此问题。

类路径扫描

对于类路径扫描,主要问题是 Equinox 不会公开标准的 jar:file: 资源。平台在中间放置一个适配器,以便库可以看到它们期望的资源协议。这有一个很好的副作用,可以使 **很多** 第三方库工作 - 它不仅仅是针对类路径扫描的修复。

线程上下文类加载器管理

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

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

这只是平台解决的问题的一小部分,但希望它能让你了解平台对 Spring 框架用户意味着什么。

获取 Spring 电子邮件

通过 Spring 电子邮件保持联系

订阅

领先一步

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

了解更多

获得支持

Tanzu Spring 在一个简单的订阅中提供 OpenJDK™、Spring 和 Apache Tomcat® 的支持和二进制文件。

了解更多

即将举行的活动

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

查看全部