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

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

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

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

我先声明一下:您即将看到的模式仅用于说明 Spring Integration 的功能;不同版本之间的语法可能有所不同,您的系统可能需要额外的预防措施。

参与 Spring Integration 的第一步是下载项目并查看示例。所以让我们从这里开始

  1. 从 svn 检出源代码svn co https://src.springframework.org/svn/spring-integration/trunk如果您不习惯使用不断变化的代码库,您也可以选择 https://src.springframework.org/svn/spring-integration/tags/ 下的一个里程碑版本,但在撰写此博客时,M4 尚未发布,我当然还是想向您展示最新功能。当您阅读此文章时,别忘了检查 M4 是否已经发布。我上次检查时,它即将孵化。
  2. 对整个项目进行构建
    $ cd build-spring-integration
    $ ant
  3. 在 Eclipse 中导入项目并配置 IVY_CACHE 变量以指向您的 ivy 缓存。这可能是一个位于 build-spring-integration 旁边的目录。
  4. 打开 HelloWorldDemo 并作为 Java 应用程序运行。如果您以前做过 这个,您将看到语法上的变化。
如果一切正常,您就启动并运行了。接下来您可以探索不同的示例。我将只描述咖啡馆示例,因为它是最有趣的配置。

在示例项目的 cafe 包中,您将找到与 著名的星巴克故事 实现相关的所有代码。为了向您介绍架构,我将从头(咖啡馆)到尾(咖啡师)地遵循一个订单

首先,订单由 CafeDemo 创建。它包含两杯饮料,一杯热的,一杯冷的。然后订单被包装成一条消息并放到“orders”通道上。监听“orders”通道的端点是一个拆分器(OrderSplitter),在 split 方法中,订单被拆分成多个饮料,这些饮料又被框架包装成单独的消息。

拆分并放到“drinks”通道后,饮料由 DrinksRouter 处理。此路由器的职责是将热饮放到“hotDrinks”通道,将冷饮放到“coldDrinks”通道。这两个通道都由不同的端点处理,这些端点分别使用 Barista 上的 prepareHotDrink 和 prepareColdDrink 方法。

让我们通过相关的代码片段来跟踪消息流:在 cafeDemo.xml bean 定义文件中,您可以看到一个 Cafe 被配置为一个 bean。<beans:bean id="cafe" class="org.springframework.integration.samples.cafe.Cafe"> <beans:property name="orderChannel" ref="orders" /> </beans:bean> 这个 bean 被 CafeDemo main 方法用于将订单消息放到订单队列中。 Cafe cafe = (Cafe) context.getBean("cafe"); DrinkOrder order = new DrinkOrder(); Drink hotDoubleLatte = new Drink(DrinkType.LATTE, 2, false); Drink icedTripleMocha = new Drink(DrinkType.MOCHA, 3, true); order.addDrink(hotDoubleLatte); order.addDrink(icedTripleMocha); for (int i = 0; i < 100; i++) { cafe.placeOrder(order); }

A<context:component-scan ...../>正在使用中cafeDemo.xml来引导 OrderSplitter 和 DrinkRouter。

OrderSplitter 散布着一些注解

  • 当您开启 annotation-config 时,@MessageEndpoint 注解告诉 Spring Integration 将这种类型的 bean 包装在一个端点中。此外,它还是 @Component 的子类型,因此您不需要编写 xml bean 定义即可让 Spring 识别它。
  • @Splitter 注解告诉 spring 使用 splitOrder 方法将包含 Order 作为有效负载的消息拆分为多个包含该 Order 中饮料的消息。
@MessageEndpoint(input="orders", output="drinks") public class OrderSplitter {
@Splitter
public List<Drink> split(Message<DrinkOrder> orderMessage) {
	return orderMessage.getPayload().getDrinks();
}

}

DrinkRouter 类似地装饰了注解,这些注解告诉 Spring Integration 将其用作路由器。从 @Router 注解方法返回的字符串被 Spring Integration 解释为输出通道。@MessageEndpoint(input="drinks") public class DrinkRouter {

@Router
public String resolveDrinkChannel(Drink drink) {
	return (drink.isIced()) ? "coldDrinks" : "hotDrinks";
}

}

路由后,消息根据其温度在 hotDrinks 或 coldDrinks 通道上可用。

配置为调用 Barista 上相应方法的端点在 xml 中配置:

您可以看到输入通道和用于发送消息的方法都已定义,因此 Spring Integration 知道该怎么做。

请注意,您不需要自己解包消息:接受有效负载类型作为输入参数也可以。如果您更改 Barista 中的方法以接受 Message并自己提取有效负载,它仍然会按预期工作。 public void prepareColdDrink(Message drinkMessage) { Drink drink = drinkMessage.getPayload(); //no changes to the rest of the code }

试玩示例,如果您有任何问题,请在论坛上发帖。您会发现他们已经非常有帮助了(主要是因为 Mark 回复了几乎所有的帖子)。下一集将介绍 EIP 的另一种实现。

获取 Spring 新闻通讯

通过 Spring 新闻通讯保持联系

订阅

领先一步

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

了解更多

获得支持

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

了解更多

即将举行的活动

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

查看所有