Spring Integration 1.0.3 示例:只需添加 OSGi

工程 | Oleg Zhurakousky | 2009 年 7 月 28 日 | ...

简介

上周,Mark Fisher 向您介绍了新的重构和简化的Spring Integration 示例,这些示例随 Spring Integration 1.0.3 的新版本发布,到目前为止,反馈非常积极。除了重构和简化现有示例外,我们还引入了几个新示例,目的是演示在基于 OSGi 的平台上运行 Spring Integration 的一些好处。在本博客中,我们将使用一个非常简单但功能强大的示例来了解 Spring Integration 和OSGi 结合使用时的一些好处,以解决当今企业的动态特性。

Spring Integration 是一个基于 POJO 的轻量级、可嵌入的消息框架,具有松耦合编程模型,旨在简化基于企业集成模式的异构系统的集成,并且无需单独的 ESB 式引擎或专有开发和部署环境。另一方面,OSGi 是一种范式,允许人们从称为 OSGi Bundle 的独立模块组合松耦合系统。从一组独立开发的模块组合系统可能不是一个新的范式,我们多年来一直在这样做(希望如此)。话虽如此,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:打开服务器视图 -> 在服务器视图中的空白处右键单击 -> 新建 -> 服务器

picture-14

选择SpringSource -> SpringSource dm Server v1.0 -> 下一步

指向您安装服务器的根目录

picture-22

单击完成

picture-3

您现在已在 STS 环境中配置了 SpringSource dm Server。启动 dm Server 并确保它成功启动并且没有错误。

假设您已经下载了 Spring Integration 示例,因此让我们使用 STS/Eclipse 提供的“将现有项目导入工作区”向导将这两个示例项目导入工作区。文件 -> 导入 -> 常规 -> 将现有项目导入工作区 -> 下一步 浏览到示例目录的位置并选择osgi-inboundosgi-outbound 项目

picture-51

单击完成 您应该会看到两个带有错误的项目。

picture-4

这些错误是预期的,因为我们的项目不知道 dm Server 目标运行时,并且我们的 dm Server 目标运行时不知道 Spring Integration bundle。让我们一次解决一个问题。首先,让我们让 dm Server 了解 Spring Integration,方法是将 Spring Integration 和相关的 bundle 部署到 dm Server 的存储库中。这是一个非常简单的过程。将org.springframework.integration-1.0.3.RELEASE.jarorg.springframework.integration.file-1.0.3.RELEASE.jar(我们的示例依赖的两个 bundle)复制到 dm Server 的repository/bundles/usr 目录中。然后在 STS 的服务器视图中双击 dm Server 的实例 -> 单击存储库选项卡,在右上角您会找到一个刷新按钮。单击它,您应该会看到 dm Server 的存储库中提供了这两个 bundle。

picture-6

现在我们需要让我们的 bundle 项目了解我们新的目标运行时。右键单击每个项目 -> 属性 -> 目标运行时 -> SpringSource dm Server (Runtime) v1.0

picture-7

现在所有错误都应该消失了。您可以准备测试这些示例

示例

这两个示例都基于非常简单且熟悉的生产者/消费者概念。第一个 bundle osgi-inbound 是一个生产者,它允许您生成一个将发送到消息通道的消息。第二个 bundle osgi-outbound 是一个消费者,它将消耗由osgi-inbound bundle 放入通道的消息,并将消息写入文件。

通过右键单击服务器实例 -> 启动来启动 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

或者您可以使用服务器视图的服务器控制台选项卡并键入

siSend "Hello World" hello.txt

并单击执行

您将看到以下内容

picture-9

然后验证您的消息是否已写入文件。

这个非常简单和简单的概念演示了基于 Spring Integration 提供的消息模型的两个系统之间的松耦合集成。但是,在现实世界中,我们在尝试集成两个系统时必须面对的问题之一是此类系统的独立生命周期,其中其行为的变化新系统的添加和/或旧系统的生命周期结束是正常现象。通常,此类更改不仅需要代码更改,还需要重新部署整个单片(例如,EAR、WAR)应用程序,然后完全重新启动服务器。Spring Integration 的 POJO 编程模型非常适合解决这些系统的松耦合特性,其中一个系统的更改很少会影响另一个系统。但是,其生命周期动态性如何?假设(在我们的小示例范围内)关于文件写入位置或方式的要求已更改。 “位置”和“方式”都是osgi-outbound bundle 的责任。在正常情况下,对osgi-outbound 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 服务注册表中的服务,从而允许当前和未来 bundle 之间实现更加松耦合但动态的协作模型。

让我们也回顾一下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"/>

此示例的目的是在osgi-inbound bundle发布的通道启动后动态订阅该通道,并将消息写入由<osgi:service/>元素配置的目录中的文件,从而体现了OSGi服务层提供的动态特性。如配置所示,osgi-inbound bundle导出的'inboundChannel' OSGi服务现在通过<osgi:reference/>元素导入。现在,由OSGi服务提供的入站通道已准备好动态接受和/或丢失订阅者。由于OSGi服务的动态特性,我们还可以更新配置或完全重新设计/重新实现osgi-outbound bundle,而不会影响系统的生产部分(osgi-inbound)。因此,让我们继续更改文件写入的目录(确保dm服务器仍在运行...事实上,在本文档的持续时间内,请忘记停止它)。

打开osgi-outbound项目 -> src -> META-INF -> spring -> osgi-outbound.xml并在'directory'配置中添加一个子目录(在本例中为'foo')picture-8保存文件。几秒钟后,您将看到您的osgi-outbound bundle已重新部署。打开OSGi或服务器控制台,并像以前一样发送另一条消息,查看新文件是否已写入您刚刚指定的目录。希望它成功了;)

结论

请记住,虽然在这个简单的示例中我们只处理两个bundle,但这些类型的生产者/消费者 bundle本身可以作为系统其他部分的网关,并且这些部分自然具有动态性。例如,假设您希望收到有关文件写入的电子邮件通知。使用SI和OSGi,您只需创建一个新的bundle来表示子系统的该部分作为osgi-inbound bundle发布的通道服务的消费者,当您不需要它时 - 通过停止或卸载此消费者来取消订阅,而不会影响系统的其余部分。事实上,您可以尝试开发另一个bundle作为osgi-inbound消费者,或者发挥您的想象力,开发另一个bundle来处理osgi-outbound bundle写入的文件。

有关更多想法和更复杂的示例,您还可以阅读Spring集成团队成员Iwein Fuld的这篇博文

最重要的是 - 集成快乐!!!

获取Spring通讯

与Spring通讯保持联系

订阅

走在前面

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

了解更多

获取支持

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

了解更多

即将举行的活动

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

查看全部