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");

应用中可声明两种变量:

  1. 流变量:仅在当前 Mule 流中可用,包括子流和私有流
  2. 会话变量:声明后在整个应用中可用

4. 传输屏障与 flow-ref

传输屏障指 HTTP 连接器、VM、JMS 等需要路径或接口才能路由消息的连接器。流变量无法跨传输屏障传递,但会话变量可在项目的所有流中访问。

当需要创建子流或私有流时,可使用 flow-ref 组件从父流或其他流引用它们。通过 flow-ref 引用的子流和私有流中,流变量和会话变量均可用。

5. 示例项目

现在我们在 Anypoint Studio 中创建包含多个流的应用,这些流通过入站和出站连接器相互通信。

先看第一个流:

Flow

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 连接器的路径决定接收接口:

Flow 1

初始流处理的消息通过入站 VM 端点到达 Flow1。Java 组件获取第一个流设置的出站属性并返回对象作为消息负载:

public Object transformMessage(
  MuleMessage message, 
  String outputEncoding) throws TransformerException {

    return (String) message.getInboundProperty("outboundKey");
}

接着为第二个流设置流变量和会话变量,然后通过 flow-ref 组件引用 Flow2

Flow 2

Flow2 中,使用 Java 组件转换消息并记录日志,同时设置流变量 F3使用 flow-ref 调用 Flow2 后,Flow1 会等待 Flow2 处理完成。

由于这些流间没有传输屏障,Flow1Flow2 中设置的流变量在双方都可用。

最终消息通过 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 获取。


原始标题:Getting Started With Mule ESB