1. 概述
Mule ESB 是一个轻量级的基于 Java 的企业服务总线。它允许开发者通过交换不同格式的数据来连接多个应用程序,数据以消息的形式进行传输。
ESB 通过提供以下核心服务展现强大能力:
- ✅ 服务创建与托管
- ✅ 服务中介
- ✅ 消息路由
- ✅ 数据转换
当需要集成多个应用程序,或预期未来会新增应用时,ESB 就显得特别有用。它尤其适用于处理多种通信协议以及需要消息路由能力的场景。
在后续章节中,我们将使用 AnyPoint Studio(可从官网下载)创建示例项目。
2. Mule 消息结构
简单来说,ESB 的核心作用是在服务间进行中介,并将消息路由到各种接口。因此它需要处理不同类型的内容或有效载荷(payload)。
消息结构分为两部分:
- 消息头:包含元数据
- 消息体:包含业务数据
消息被嵌入在消息对象中。我们可以从上下文中获取消息对象,并通过 Mule 流中的自定义 Java 组件和转换器修改其属性和有效载荷。
每个应用由一个或多个流组成。在流中,我们可以使用组件来访问、过滤或修改消息及其属性。
例如,通过实现 org.mule.api.lifecycle
包中的 Callable 接口,可以在 Java 组件中获取消息实例:
public Object onCall(MuleEventContext eventContext) throws Exception {
MuleMessage message = eventContext.getMessage();
message.setPayload("Message payload is changed here.");
return message;
}
3. 属性与变量
消息元数据由属性组成,变量则表示消息的附加数据。属性和变量的作用域决定了它们在消息生命周期中的可用性。根据作用域,属性分为两种类型:入站属性和出站属性。
入站属性包含防止消息在跨流传输时混乱的元数据。这类属性不可变且无法被用户修改,仅在当前流中存在——消息离开流后即消失。
出站属性可由 Mule 自动设置,或通过流配置手动设置。这些属性是可变的。当消息通过传输屏障进入另一个流时,它们会转换为入站属性。
通过调用各自作用域的 setter/getter 方法可以操作属性:
message.setProperty(
"outboundKey", "outboundpropertyvalue", PropertyScope.OUTBOUND);
String inboundProp = (String) message.getInboundProperty("outboundKey");
应用中可声明两种变量:
- 流变量:仅在当前 Mule 流中可用,包括子流和私有流
- 会话变量:声明后在整个应用中可用
4. 传输屏障与 flow-ref
传输屏障指 HTTP 连接器、VM、JMS 等需要路径或接口才能路由消息的连接器。流变量无法跨传输屏障传递,但会话变量可在项目的所有流中访问。
当需要创建子流或私有流时,可使用 flow-ref 组件从父流或其他流引用它们。通过 flow-ref 引用的子流和私有流中,流变量和会话变量均可用。
5. 示例项目
现在我们在 Anypoint Studio 中创建包含多个流的应用,这些流通过入站和出站连接器相互通信。
先看第一个流:
HTTP 监听器配置如下:
<http:listener-config name="HTTP_Listener_Configuration"
host="localhost" port="8081" doc:name="HTTP Listener Configuration"/>
流组件必须包含在
<flow name="Flow">
<http:listener
config-ref="HTTP_Listener_Configuration"
path="/" doc:name="HTTP"
allowedMethods="POST"/>
<logger message="Original
paylaod: #[payload]"
level="INFO" doc:name="Logger"/>
<custom-transformer
class="com.baeldung.transformer.InitializationTransformer"
doc:name="Java"/>
<logger message="Payload After Initialization: #[payload]"
level="INFO" doc:name="Logger"/>
<set-variable variableName="f1"
value="#['Flow Variable 1']" doc:name="F1"/>
<set-session-variable variableName="s1"
value="#['Session variable 1']" doc:name="S1"/>
<vm:outbound-endpoint exchange-pattern="request-response"
path="test" doc:name="VM"/>
</flow>
流中引用了配置的 HTTP 监听器,通过 logger 记录 POST 方法接收的负载。随后放置自定义 Java 转换器:
public Object transformMessage(
MuleMessage message,
String outputEncoding) throws TransformerException {
message.setPayload("Payload is transferred here.");
message.setProperty(
"outboundKey", "outboundpropertyvalue", PropertyScope.OUTBOUND);
return message;
}
转换器类必须继承 AbstractMessageTransformer。我们在类中设置了出站属性。
转换后的负载通过 logger 记录,然后设置流变量和会话变量。最后通过出站 VM 连接器发送负载。VM 连接器的路径决定接收接口:
初始流处理的消息通过入站 VM 端点到达 Flow1。Java 组件获取第一个流设置的出站属性并返回对象作为消息负载:
public Object transformMessage(
MuleMessage message,
String outputEncoding) throws TransformerException {
return (String) message.getInboundProperty("outboundKey");
}
接着为第二个流设置流变量和会话变量,然后通过 flow-ref 组件引用 Flow2:
在 Flow2 中,使用 Java 组件转换消息并记录日志,同时设置流变量 F3。使用 flow-ref 调用 Flow2 后,Flow1 会等待 Flow2 处理完成。
由于这些流间没有传输屏障,Flow1 和 Flow2 中设置的流变量在双方都可用。
最终消息通过 VM 返回给 HTTP 请求方。所有 VM 配置为请求-响应模式。
通过 REST 客户端(URL: localhost:8081
)发送任意 JSON 数据即可调用此应用。
6. Maven Archetype
使用 Mulesoft 的 Maven archetype 构建 Mule ESB 项目:
首先在 Maven 的 settings.xml 中添加插件组:
<pluginGroups>
<pluginGroup>org.mule.tools</pluginGroup>
</pluginGroups>
然后添加 profile 指定 Mulesoft 仓库:
<profile>
<id>Mule Org</id>
<activation>
<activeByDefault>true</activeByDefault>
</activation>
<repositories>
<repository>
<id>mulesoft-releases</id>
<name>MuleSoft Repository</name>
<url>https://repository.mulesoft.org/releases/</url>
<layout>default</layout>
</repository>
</repositories>
</profile>
最后通过 archetype 创建项目:
mvn mule-project-archetype:create -DartifactId=muleesb -DmuleVersion=3.9.0
配置完成后,使用 mvn package
生成可部署归档文件,将其放入独立 Mule 服务器的 apps 文件夹即可。
7. 通过 MuleSoft 仓库部署独立服务器
如需独立 Mule 服务器,可修改 pom.xml 从 MuleSoft 仓库获取:
<plugin>
<groupId>org.mule.tools.maven</groupId>
<artifactId>mule-maven-plugin</artifactId>
<version>2.2.1</version>
<configuration>
<deploymentType>standalone</deploymentType>
<muleVersion>3.9.0</muleVersion>
</configuration>
<executions>
<execution>
<id>deploy</id>
<phase>deploy</phase>
<goals>
<goal>deploy</goal>
</goals>
</execution>
</executions>
</plugin>
8. 总结
本文介绍了构建 Mule ESB 应用的核心概念,并通过示例项目演示了这些概念的实际应用。现在你可以使用 Anypoint Studio 开发满足各种需求的 ESB 应用了。
完整项目代码可在 GitHub 获取。