1.2. 基本 Java DSL 语法

什么是 DSL?

域特定语言(DSL)是专为特殊用途而设计的微型语言。DSL 不需要逻辑上完成,但需要足够的表达力来描述所选域中的问题。通常,DSL 不需要 专用的解析程序、解释器或编译器。DSL 可以在现有面向对象的主机语言之上 piggyback,提供 DSL 构造在主机语言 API 中彻底构造。

在假设 DSL 中请考虑以下命令序列:

command01;
command02;
command03;

您可以将这些命令映射到 Java 方法调用,如下所示:

command01().command02().command03()

您甚至可将块映射到 Java 方法调用。例如:

command01().startBlock().command02().command03().endBlock()

DSL 语法由主机语言 API 的数据类型隐式定义。例如,Java 方法的返回类型决定了您可以法律地调用哪些方法(与 DSL 中的下一个命令相同)。

路由器规则语法

Apache Camel 定义了一个 路由器 DSL,用于定义路由规则。您可以使用此 DSL 在 RouteBuilder.configure() 实施的正文中定义规则。图 1.1 “本地路由规则” 展示了定义本地路由规则的基本语法概述。

图 1.1. 本地路由规则

本地路由规则

本地规则始终以 ("EndpointURL") 方法开头,该方法指定路由规则的消息(使用者端点)来源。然后您可以在规则中添加任意较长的处理器链(如 filter())。您通常通过 to("EndpointURL") 方法关闭规则,它指定通过规则传递的消息的目标(制作端点)。但是,始终不需要以 to() 结束规则。在规则中指定消息目标的方法有其他方法。

注意

您还可以通过使用特殊处理器类型(如 intercept()、exception()errorHandler () )启动规则来定义全局路由规则。全局规则不在本指南的讨论范围内。

消费者和制作者

本地规则始终通过定义消费者端点(使用 ("EndpointURL") )开始,并且通常(但并不总是)通过定义制作者端点(使用 to("EndpointURL") )来结束。端点 URL EndpointURL 可以使用部署时配置的任何组件。例如,您可以使用文件端点、file:MyMessageDirectory、Apache CXF 端点、cxf:MyServiceName 或 Apache ActiveMQ 端点 activemq:queue:MyQName。有关组件类型的完整列表,请参阅 Apache Camel 组件参考

交换

Exchange 对象由元数据增强的消息组成。交换是 Apache Camel 中的集中重要性,因为交换是通过路由规则传播消息的标准表单。交换的主要特征是,如下所示:

  • message 这个过程中,使用交换封装的当前消息。在通过路由进行交换过程中,可能会修改此消息。因此,在路由开始时的 In 消息通常和路由末尾的 In 消息 不同org.apache.camel.Message 类型提供了消息的通用模型,包括以下部分:

    • 正文.
    • 标头.
    • 附件.

    务必要意识到这是消息 的通用 模型。Apache Camel 支持各种协议和端点类型。因此,无法 标准化邮件正文或邮件标题的格式。例如,JMS 消息正文与 HTTP 消息正文或 Web 服务消息的正文具有完全不同的格式。因此,正文和标头被声明为 对象类型。然后,正文和标头的原始内容由创建交换实例的端点决定(即,端点会出现在 from() 命令中)。

  • out messageourier- burdenis a temporary holding area for a reply message or a transformed message.某些处理节点(特别是 to() 命令)可以将 In 消息视为请求,将其发送到制作者端点,然后从该端点接收回复来修改当前消息。然后将回复消息插入到交换中的 Out message 插槽。

    通常,如果当前节点设置了 Out 消息,Apache Camel 会在将交换传递到路由中的下一个节点之前修改交换:旧的 In 消息被丢弃,并将 Out 消息移到 In message slot。因此,回复会成为新的当前消息。如需了解 Apache Camel 如何在路由中连接节点的详情,请参考 第 2.1 节 “Pipeline 处理”

    然而,有一个特殊情形: Out 消息的处理方式有所不同。如果路由开头的消费者端点预期回复消息,则路由末尾的 Out 消息将被视为消费者端点的回复消息(在这种情况下,最终节点 必须创建 Out 消息,或者消费者端点会挂起)。

  • 消息交换模式(MEP)admission-IFL-ffects 在路由中交换和端点之间的交互,如下所示:

    • 消费者端点 the consumer 端点创建原始交换,设置 MEP 的初始值。初始值表示消费者端点是否期望收到回复(例如,InOut MEP)是否不是(例如 InOnly MEP)。
    • 生产者端点 时间为 MEP 影响生产者端点,该端点会影响路由所遇到的生产者端点(例如,交换通过 to() 节点时)。例如,如果当前 MEP 是 InOnly,则 to() 节点不应该从端点接收回复。有时您需要更改当前的 MEP,以便自定义与制作者端点的交互。如需了解更多详细信息,请参阅 第 1.4 节 “Endpoints”
  • 交换当前消息元数据的命名属性列表。

消息交换模式

使用 Exchange 对象可轻松地将消息处理规范化为 不同的消息交换模式。例如,异步协议可以定义一个 MEP,它由一个消息组成,消息从消费者端点流到制作者端点( 仅适用 MEP)。另一方面,RPC 协议可能会定义由请求消息和回复消息(一个 InOut MEP)组成的 MEP。目前,Apache Camel 支持以下 MEPs:

  • InOnly
  • RobustInOnly
  • InOut
  • InoptionalOut
  • OutOnly
  • RobustOutOnly
  • OutIn
  • OutOptionalIn

其中,这些消息交换模式由枚举类型中的常数来表示,即 org.apache.camel.ExchangePattern

分组交换

有时,有一个封装多个交换实例的单一交换很有用。为了实现此目的,您可以使用一个 分组的交换。分组交换基本上是一个交换实例,其中包含存储在 Exchange.GROUPED_EXCHANGE 交换属性中的 java.util.List 的 Exchange 对象。有关如何使用分组交换的示例,请参阅 第 8.5 节 “聚合器”

处理器

处理器 是路由中的节点,可访问和修改通过路由进行的交换流。处理器可以使用 表达式或 predicate 参数,用于修改其行为。例如,图 1.1 “本地路由规则” 中显示的规则包含一个 filter() 处理器,该处理器使用 xpath() predicate 作为其参数。

表达式和 predicates

表达式(评估为字符串或其他数据类型)和 predicates(显示为 true 或 false)经常作为内置处理器类型的参数。例如,以下过滤器规则会传播 In 消息,只有在 foo 标头等于值 bar 时:

from("seda:a").filter(header("foo").isEqualTo("bar")).to("seda:b");

如果过滤器由 predicate、header("foo").isEqualTo("bar") 授权。要根据消息内容构建更加复杂的 predicates 和表达式,您可以使用以下一种表达式和谓词语言(请参阅 第 II 部分 “路由表达式和指定语言”)。