使用Mule 2.0基于模式的开发 part1
Submitted by dirksenrademakers on Wed, 2008/05/28 - 2:05am.
Translated by alloyer on Fri,2008/07/31 - 10:00am.
关键字:ESB Mule Patterns SOA
引言:你还在使用像IBM,Tibco这样的传统的庞大的集成提供商之一的集成产品,并且正在寻找一款更加轻量级的解决方案吗?这里的两篇关于Mule和Apache ServiceMix的文章会让你对开源ESB大开眼界。如果你已经比较熟悉Mule或者Apache ServiceMix了,这两篇文章会为你提供对这些开源ESB产品的最新版本一些见解,并展示如何迈进集成解决方案的设计。
这两篇文章将尝试揭密基于ESB的Java Business Integration实现(ServiceMix)与传统的成熟ESB实现(Mule)间的辨论。在这两篇文章中,我们将使用Mule和ServiceMix实现一个集成解决方案,来说明两种方法都有道理并且他们之间实际上是有相当大的重叠部分的。
在第一篇文章中,我们将关注Mule,确切地讲是Mule 2.0,它是Mule项目的最新版本。第二篇文章是关于Apache ServiceMix的,它将会在未来的两周内完成。
Mule 2.0简介
在进入基于模式的开发方法前,我们先浏览一下Mule 2.0的架构。如果你已经熟悉Mule了,你应该注意我们在这里讨论的是Mule 2.0的架构,它是Mule 1.4.x的接班人,现在已经发布了。并且这两个版本间,架构有了相当大的改变。在这篇文章的最后,有一个指向MuleSource网站的链接,这个页面上会简要地讲解两个版本间的不同之处。
开始Mule 2.0架构的不错方式是看一下,一条消息是怎样被Mule处理的,如图1所示.
图1 典型的Mule消息流概述。在某一消息通道中接收到一条消息,执行组件和入站、出站路由的集成逻辑,然后将消息传送到目标消息通道中。
从图1中可以看出,对典型的Mule消息流,我们需要定义一个入站路由,它监听在特定的消息队列上。消息队列的样式遵照Hohpe和Wool撰写的很有名气的Enterprise Integration Patterns一书中的描述。本质上,消息通道只是传输消息。一个消息通道可以是一个JMS队列,一个文件目录或者一个HTTP连接。当一条消息通过入站路由处理后,它就被传送给一个组件的实现中,这个组件可以是你自己编写的POJO类,也可以是用Spring配置的Bean,脚本实现甚至是BPEL流程。这个处理组件的响应结果会通过出站路由被传送到输出消息队列中。
建立Mule 2.0消息流
前面我们仅仅谈论的是理论。现在来增加一个有实际意义和有趣的东西,我们来看一下Mule的一些处理消息的配置,这个消息来自JMS队列,它包含了你的名字。这个处理过程将为你的名字加一个"Hello"前缀,并将它转发到另一个JMS队列。
如表1所示,Mule配置需要Mule 2.0标记。这个配置需要Mule 2.0代理,你可以从MuleSource站点上下载到。
表1 Mule 2.0简单消息流配置
- <mule xmlns="http://www.mulesource.org/schema/mule/core/2.0"
- xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
- xmlns:spring="http://www.springframework.org/schema/beans"
- xmlns:jms="http://www.mulesource.org/schema/mule/jms/2.0"
- xsi:schemaLocation="
- http://www.springframework.org/schema/beans
- http://www.springframework.org/schema/beans/spring-beans-2.0.xsd
- http://www.mulesource.org/schema/mule/core/2.0
- http://www.mulesource.org/schema/mule/core/2.0/mule.xsd
- http://www.mulesource.org/schema/mule/jms/2.0
- http://www.mulesource.org/schema/mule/jms/2.0/mule-jms.xsd”>
- <jms:activemq-connector name=”jmsCon” brokerURL=”tcp://localhost:61616”
- <spring:bean id=”helloBean” class=”esb.example.HelloBean”>
- <spring:property name=”prefix” value=”hello “ />
- </spring:bean>
- <model name=”helloModel”>
- <service name=”helloService”>
- <inbound>
- <jms:inbound-endpoint queue=”in-queue” />
- </inbound>
- <component>
- <spring-object bean=”helloBean” />
- </component>
- <outbound>
- <outbound-pass-through-router>
- <jms:outbound-endpoint queue=”out-queue” />
- </outbound-pass-through-router>
- </outbound>
- </service>
- </model>
- </mule>
表1的例子很好的展示了Mule提供的功能特性。首先,可以看出非常容易地就可以把Mule连接到一个运行的ActiveMQ代理上,所以你可以进行JMS消息交换。这些是由jms:activemq-connector完成的。我们还可以看到消息流的入站部分由inbound元素定义,在这个元素里,我们可以定义一个入站接入点endpoint或者特定的路由器router。在这个例子中,我们只是配置了一个入站接入点,监听在JMS队列上。注意入站接入点要有一个具体的jms名字空间,这个前缀指向mule-jms结构定义,mule-jms结构定义了JMS入站接入点的队列特性,所以你可以使用你的IDE代码自动补充功能创建这些元素。一个标准的,不因一种技术而定的入站接入点定义了一个地址属性,这个属性里,你可以使用JMS协议前缀,jms://in-queue,来定义JMS队列。使用这种基本结构的方式你可以得到一个更加可描述和更简单的方式定义队列、主题和所有其他支持的技术的入站接入点。
这个例子还展示了Spring框架折开箱即用的集成方式。这种方式下,我们可以使用一个使用类名为Mule组件指定一个POJO类,这个例子中提供了spring-object子元素的使用。当你使用这个元素时,你告诉Mule使用Spring把具体的名称处理为Spring bean。在这个例子里,我们引用了表1中定义的HellBean,而它的实现仅仅是表2中定义的一个基本的POJO类。
表2 消息流例子中使用的组件:HelloBean
- public class HelloBean {
- private String prefix;
- public String hello(String name) {
- return prefix + name;
- }
- public void setPrefix(String prefix) {
- this.prefix = prefix;
- }
- }
HelloBean中定义了一个由Mule配置文件注入的前缀属性。这个组件实现中有趣的是Mule是怎样确定调用哪一个方法的?默认情况下,Mule容器检查组件的实现,看其中是否有含有输入类型与消息的有效负载类型相匹配的公共方法。在这个例子中,有效负载中字符串实现的你的名字,所以HelloBean中的两个方法hello和setPrefix会被Mule容器发现。然而,默认中,Mule容器首先会考虑有返回值的方法,而不是空返回值void的方法。这就意味着,在这个例子中,hello方法会被Mule容器调用。在Mule架构中,这被称为入口点解析,默认情况下,入口点解析方法会被使用。其他的入口点解析机制也可以使用,如果需要更复杂的逻辑,你甚至可以自己进行实现。
Mule配置的最后一部分负责将HelloBean组件的返回值路由到out-queue JMS队列中。在这个例子中,我们使用了outbound-pass-through-router,它仅仅将消息传递给了一个特定的接入点。Mule还提供了基于内容路由的路由器,以及其他的方式来实现更加复杂的路由逻辑,在后面更大的实例中我们会看到这一点。
这是一个非常基础的例子。不管怎样,它展示了可以用于复杂集成逻辑的架构组件的使用。在下一部分中,我们将向你通过一个更加复杂的实现向你展示Mule的更多的特性。