1.2. 基本 Java DSL 语法
什么是 DSL?
域特定语言(DSL)是一种专为特殊目的设计的微语言。DSL 不必以逻辑方式完成,但需要足够的表达能力来描述所选域中的问题。通常,DSL 不需要 专用的解析器、解释器或编译器。DSL 可以在现有对象导向型主机语言之上进行 piggyback,只要提供的 DSL 结构被完全映射到主机语言 API 中的结构。
在 hypothetical 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. 本地路由规则
本地规则始终以 from ("EndpointURL")
方法开头,它指定了路由规则的消息源(消费者端点)。然后,您可以在规则中添加任意较长的处理器链(例如 filter ()
)。您通常使用 to ("EndpointURL")
方法结束该规则,它为通过规则传递的消息指定目标(生成端点)。但是,并非始终需要使用 to ()
结束规则。在规则中指定消息目标有其他方法。
您还可以通过启动带有特殊处理器类型的规则(如 intercept ()
、exception ()
或 errorHandler ()
)来定义全局路由规则。全局规则不在本指南范围内。
使用者和制作者
本地规则始终首先定义消费者端点,使用 from ("EndpointURL")
),通常(但不始终)通过定义制作者端点(使用 to ("EndpointURL")
)结束。端点 URL EndpointURL 可以使用部署时配置的任何组件。例如,您可以使用文件端点 file:MyMessageDirectory
、Apache CXF 端点 cxf:MyServiceName
或 Apache ActiveMQ 端点 activemq:queue:MyQName
。有关组件类型的完整列表,请参阅 Apache Camel 组件参考。
Exchanges
Exchange 对象 由一条消息组成,由元数据增强。交换是 Apache Camel 中的核心重要性,因为交换是通过路由规则传播消息的标准形式。交换的主要组成部分是,如下所示:
在 message iwl-wagonis 中,当前由交换封装的消息。随着交换通过路由进行,可以修改此消息。因此,路由启动时的 In 消息通常与路由末尾的 In 消息不同。
org.apache.camel.Message
类型提供消息的通用模型,其中包含以下部分:- 正文。
- 标头.
- 附件.
务必要意识到这是消息 的通用 模型。Apache Camel 支持各种协议和端点类型。因此,无法 标准化消息正文或消息标头的格式。例如,JMS 消息的正文将具有对 HTTP 消息正文或 Web 服务消息的完全不同的格式。因此,正文和标头被声明为
对象类型
。然后,正文和标头的原始内容由创建交换实例的端点(即,端点出现在from ()
命令中)决定。出 一条 message iwl-unmarshalis 是一个临时区域,用于回复消息或转换的消息。某些处理节点(特别是
to ()
命令)可以通过将 In 消息视为请求来修改当前消息,将其发送到制作者端点,然后从该端点收到回复。然后,回复消息会插入到交换中的 Out 消息插槽中。通常,如果当前节点设置了 Out 消息,则 Apache Camel 会在将其传递给路由中的下一节点前修改交换,旧的 In 信息将丢弃,并将 Out 消息移到 In 消息插槽中。因此,回复会成为新的当前消息。有关 Apache Camel 如何在路由中连接节点的详细信息,请参阅 第 2.1 节 “Pipeline 处理”。
然而,存在一条特殊情况,其中 Out 消息被以不同的方式处理。如果路由开始时的消费者端点期望回复消息,则路由结尾处的 Out 消息将作为消费者端点的回复消息(以及这种情况,最终节点 必须创建一个 Out 消息或消费者端点挂起)。
消息交换模式(MEP)用于处理路由中的交换和端点之间的交互,如下所示:
- 创建原始交换的消费者端点( consumer 端点)会设置 MEP 的初始值。初始值指示消费者端点是否应该收到回复(例如,InOut MEP)还是不(例如,InOnly MEP)。
-
生产者端点 mvapich-busybox MEP 会影响交换在路由中遇到的制作者端点(例如,当交换通过
to ()
节点时)。例如,如果当前 MEP 是 InOnly,则to ()
节点不会预期从端点接收回复。有时,您需要更改当前的 MEP,以自定义交换与制作者端点的交互。如需了解更多详细信息,请参阅 第 1.4 节 “Endpoints”。
- 交换包含当前消息元数据的命名属性的 exchange 属性列表。
消息交换模式
通过使用 Exchange
对象,可以将消息处理规范化为不同的 消息交换模式。例如,异步协议可能会定义一个 MEP,其中包含一个从消费者端点流到生成者端点(仅限 MEP)的单个消息。另一方面,RPC 协议可能会定义一个由请求消息和回复消息( InOut MEP)组成的 MEP。目前,Apache Camel 支持以下 MEP:
-
InOnly
-
RobustInOnly
-
InOut
-
InOptionalOut
-
OutOnly
-
RobustOutOnly
-
OutIn
-
OutOptionalIn
其中,这些消息交换模式由枚举类型 org.apache.camel.ExchangePattern
表示。
分组交换
有时,拥有封装多个交换实例的单个交换很有用。为此,您可以使用一组 的交换。分组交换基本上是一个交换实例,其中包含存储在 Exchange.GROUPED_EXCHANGE
Exchange
属性中的 java.util.List
的 Exchange 对象。有关如何使用分组交换的示例,请参阅 第 8.5 节 “聚合器”。
处理器
处理器 是路由中的节点,可以访问和修改通过路由的交换流。处理器可以采用 expression 或 predicate 参数来修改其行为。例如,图 1.1 “本地路由规则” 中显示的规则包含一个 filter ()
处理器,它使用 xpath ()
predicate 作为其参数。
表达式和 predicates
表达式(评估字符串或其他数据类型)和 predicates (等于 true 或 false)通常作为内置处理器类型的参数。例如,只有在 foo
标头等于值 bar
时,以下过滤规则传播 In 信息:
from("seda:a").filter(header("foo").isEqualTo("bar")).to("seda:b");
其中,过滤器由 predicate, header ("foo").isEqualTo ("bar")
。要根据消息内容构建更复杂的 predicates 和 表达式,您可以使用表达式和 predicate 语言之一(请参阅 第 II 部分 “路由表达式和 predicates 语言”)。