先行一步
VMware 提供培训和认证,助您快速发展。
了解更多Spring Integration 是一个基于 POJO 的轻量级、可嵌入的消息传递框架,它采用一种松耦合的编程模型,旨在简化基于 企业集成模式 的异构系统集成,而无需单独的 ESB 引擎或专有的开发和部署环境。另一方面,OSGi 是一种范式,它允许从称为 OSGi Bundles 的独立模块构建松耦合的系统。从一组独立开发的模块构建系统可能不是什么新范式,我们(希望如此)已经这样做了很多年。话虽如此,OSGi 模块化的真正好处并非来自于其静态打包模型,而是来自于对其部署和运行时动态性的理解,以及它如何很好地适应当今业务流程的动态性。
那么,让我们通过一个简单的例子看看基于消息交换的集成和OSGi 的动态性如何互补,从而实现一个非常强大且动态的系统。
Spring Integration 示例与 Spring Integration 的发行版一起提供。您也可以从这里单独下载。为了简化,这些示例被开发为 SpringSource Tool Suite (STS) 项目,同时利用 dm Server 工具快速集成 SpringSource dm Server - 一个基于 OSGi 和 Spring 的企业 Java 平台。然而,作为符合 OSGi 规范的项目,这些示例可以在任何配置正确的 OSGi 平台上充分运行。
要配置 STS/dm Server 环境,请按照以下步骤操作
从 此处 下载并解压 STS 从 此处 下载并解压 SpringSource dm Server
Spring Source Tool Suite v2.1.x 将自带预配置的 SpringSource dm Server,但了解如何手动配置它仍然有所帮助。打开 STS 并配置 dm Server:打开Server View -> 在 Server 视图的空白处右键单击 -> New -> Server
选择 SpringSource -> SpringSource dm Server v1.0 -> Next
指向您安装服务器的根目录
点击Finish
您现在已经在 STS 环境中配置了 SpringSource dm Server。启动 dm Server 并确保它成功启动且没有错误。
假设您已经下载了 Spring Integration 示例,现在让我们使用 STS/Eclipse 提供的“Import Existing Projects into the workspace”向导将这两个示例项目导入工作区。File -> Import -> General -> Existing Projects into Workspace -> Next 浏览到 samples 目录的位置并选择 osgi-inbound 和 osgi-outbound 项目
点击Finish。您应该会看到两个项目有错误。
这些错误是预料之中的,因为我们的项目不知道 dm Server Target Runtime,而我们的 dm Server Target Runtime 不知道 Spring Integration 包。让我们一个一个地解决问题。首先让 dm Server 知道 Spring Integration,方法是将 Spring Integration 及其依赖的包部署到 dm Server 的存储库中。这是一个非常简单的过程。将 org.springframework.integration-1.0.3.RELEASE.jar 和 org.springframework.integration.file-1.0.3.RELEASE.jar(我们的示例依赖的两个包)复制到 dm Server 的 repository/bundles/usr 目录中。然后在 STS 的 Server 视图中双击 dm Server 实例 -> 点击 Repository 选项卡,在右上角您会找到一个 Refresh 按钮。点击它,您应该会看到这两个包在 dm Server 的存储库中可用。
现在我们需要让我们的 bundle 项目知道新的 Target Runtime。右键单击每个项目 -> Properties -> Target Runtimes -> SpringSource dm Server (Runtime) v1.0
通过右键单击服务器实例 -> Start 来启动 dm Server
通过简单地将 osgi-inbound 项目拖放到 dm Server 实例上来部署 osgi-inbound。几秒钟后,您应该会看到启动成功的消息
[2009-07-27 21:56:49.040] onnection(5)-172.16.12.1 <SPDE0010I> Deployment of 'org.springframework.integration.samples.osgi.inbound' version '1.0.3' completed.
然后对 osgi-outbound bundle 执行相同的操作
[2009-07-27 21:58:45.220] onnection(8)-172.16.12.1 <SPDE0010I> Deployment of 'org.springframework.integration.samples.osgi.outbound' version '1.0.3' completed.
现在您已准备好测试这些 bundle 提供的功能。为了使其更有趣,我们通过 OSGi 控制台启用了命令行接口 (CLI),您可以通过提供命令、消息以及要将消息写入的文件名来与 osgi-inbound bundle 交互。您可以通过以下方式连接到 OSGi 控制台
telnet localhost 2401
或者您可以使用 Server 视图的 Server Console 选项卡并输入
siSend "Hello World" hello.txt
然后点击Execute
您将看到以下内容
去验证您的消息是否已写入文件。
这个非常简单且微不足道的概念展示了基于 Spring Integration 提供的消息模型,两个系统之间的松耦合集成。然而,在现实世界中,我们在尝试集成两个系统时必须面对的问题之一是这些系统的独立生命周期,其中行为的变化、新系统的添加和/或旧系统的生命周期结束是正常的发生。通常,此类变化不仅需要代码更改,还需要在完全重启服务器后重新部署整个单体(例如,EAR、WAR)应用程序。Spring Integration 的 POJO 编程模型非常适合处理这些系统的松耦合特性,其中一个系统的更改很少影响另一个系统。但是它的生命周期动态性如何呢?让我们假设(在我们这个小示例的范围内)关于文件应该写入何处或如何写入的要求已经改变了。无论是“何处”还是“如何”,都是 osgi-outbound bundle 的责任。在正常情况下,对 osgi-outbound bundle 功能的任何更改都需要完全刷新系统(即,重新部署整个系统并重启服务器)。当您的系统仅由两个 bundle 组成时,这可能不是一个大问题。但如果 bundle 数量超过两个呢?仅仅因为消息应该写入的目录发生了变化,或者引入了一个新子系统应该记录每条传入消息,您是否准备好重建和重新部署打包为 WAR 或 EAR 的整个系统?这就是 OSGi 及其服务层以及最重要的是 OSGi 服务动态性提供巨大帮助的地方。所以让我们接受上述示例需求,看看如何基于扩展当前示例来实现它们。首先,让我们回顾一下 osgi-inbound bundle 的应用程序上下文配置
<osgi:service id="inboundService" ref="inboundChannel"
interface="org.springframework.integration.channel.SubscribableChannel"/>
<integration:publish-subscribe-channel id="inboundChannel"/>
<integration:gateway id="inboundGateway"
service-interface="org.springframework.integration.samples.osgi.inbound.InboundGateway"
default-request-channel="inboundChannel"/>
正如您所见,一个非常简单的配置,它定义了一个网关代理,允许以 POJO 的方式发送消息,该消息将存入配置为发布/订阅通道的入站通道。然而,更有趣的是,该通道已通过 `
我们再看看 osgi-outbound bundle 的应用程序上下文配置。
<osgi:reference id="filesIn"
interface="org.springframework.integration.channel.SubscribableChannel"/>
<file:outbound-gateway id="filesOut"
request-channel="filesIn"
directory="${java.io.tmpdir}/spring-integration-samples/output"
delete-source-files="true"/>
此 bundle 的目标是在 osgi-inbound bundle 启动后立即动态订阅其发布的通道,并将消息写入由 `
打开 osgi-outbound 项目 -> src -> META-INF -> spring -> osgi-outbound.xml,并在 'directory' 配置中添加一个子目录(在本例中是 'foo') 保存文件。几秒钟后,您将看到您的 osgi-outbound bundle 已重新部署。打开 OSGi 或 Server 控制台,像之前一样发送另一条消息,看看新文件是否已写入您刚刚指定的目录。希望它成功了 ;)
有关更多想法和更复杂的示例,您可能还会喜欢阅读 Spring Integration 团队成员 Iwein Fuld 的这篇文章
最重要的是 - 集成愉快!!!