|
如需使用最新稳定版本,请使用 Spring Integration 7.0.4! |
Apache Camel 支持
Spring Integration 提供 API 和配置,以便与在同一应用上下文中声明的 Apache Camel 端点进行通信。
您需要将以下依赖项包含到您的项目中:
-
Maven
-
Gradle
<dependency>
<groupId>org.springframework.integration</groupId>
<artifactId>spring-integration-camel</artifactId>
<version>6.4.10</version>
</dependency>
compile "org.springframework.integration:spring-integration-camel:6.4.10"
Spring Integration 和 Apache Camel 实现了企业集成模式,并提供了便捷的方式来组合它们,但这两个项目在 API 和抽象实现方面采用了不同的方法。
Spring Integration 完全依赖于 Spring Core 提供的依赖注入容器。
它使用了众多其他 Spring 项目(如 Spring Data、Spring AMQP、Spring for Apache Kafka 等)来实现其通道适配器。
它还使用 MessageChannel 抽象作为一等公民,开发人员在组合其集成流程时需要了解这一点。
另一方面,Apache Camel 没有提供消息通道的一等公民抽象,而是建议通过内部交换来组合其路由,这些交换对 API 是隐藏的。
此外,在 Spring 应用程序中使用它还需要一些额外的 依赖项和配置。
即使最终的企业集成解决方案中各部分的实现方式并不重要,开发者体验和高效生产力也是被考虑在内的因素。
因此,开发者可能会出于多种原因选择其中一个框架,或者在目标系统支持存在差距时同时使用两者。
Spring Integration 和 Apache Camel 应用程序可以通过它们实现了通道适配器的许多外部协议进行交互。
例如,Spring Integration 流可以将记录发布到 Apache Kafka 主题,该主题由消费者端的 Apache Camel 端点消费。
或者,Apache Camel 路由可以将数据写入 SFTP 文件目录,而 Spring Integration 的 SFTP 入站通道适配器会轮询该目录。
或者,在同一个 Spring 应用上下文中,它们可以通过 ApplicationEvent 抽象层 进行通信。
为了简化开发流程并避免不必要的网络跳变,Apache Camel 提供了一个 模块,用于通过消息通道与 Spring Integration 进行通信。
只需从应用程序上下文中获取一个 MessageChannel 的引用,即可发送或消费消息。
当 Apache Camel 路由作为消息流的发起者,而 Spring Integration 仅作为解决方案的一部分发挥辅助作用时,这种方式效果良好。
为了获得类似的开发者体验,Spring Integration 现在提供了一个通道适配器来调用 Apache Camel 端点,并可选择性地等待回复。
由于从 Spring Integration API 和抽象的角度来看,订阅 MessageChannel 以消费 Apache Camel 消息已足够,因此不存在入站通道适配器。
Apache Camel 的出站通道适配器
The CamelMessageHandler是一个AbstractReplyProducingMessageHandler实现,支持单向(默认)和请求 - 回复两种模式。
它使用org.apache.camel.ProducerTemplate将消息发送(或发送并接收)到org.apache.camel.Endpoint中。
交互模式可通过ExchangePattern选项进行控制(该选项可在运行时根据请求消息通过SpEL表达式进行评估)。
目标Apache Camel端点可以显式配置,也可以配置为在运行时通过SpEL表达式评估的表达式。
否则,它将回退到ProducerTemplate上提供的defaultEndpoint。
除了指定端点外,还可以提供内联的显式LambdaRouteBuilder,例如用于调用某个Apache Camel组件,而该组件在Spring Integration中没有对应的通道适配器支持。
此外,可以提供 HeaderMapper<org.apache.camel.Message>(CamelHeaderMapper 是默认实现),以确定在 Spring Integration 和 Apache Camel 消息之间映射哪些标头。
默认情况下,所有标头都会被映射。
The CamelMessageHandler 支持一种 async 模式,调用 ProducerTemplate.asyncSend() 并生成一个 CompletableFuture 用于回复处理(如果有)。
exchangeProperties 可以通过 SpEL 表达式进行自定义,该表达式的计算结果必须为 Map。
如果未提供 ProducerTemplate,则将通过从应用程序上下文中解析的 CamelContext Bean 创建它。
@Bean
@ServiceActivator(inputChannel = "sendToCamel")
CamelMessageHandler camelService(ProducerTemplate producerTemplate) {
CamelHeaderMapper headerMapper = new CamelHeaderMapper();
headerMapper.setOutboundHeaderNames("");
headerMapper.setInboundHeaderNames("testHeader");
CamelMessageHandler camelMessageHandler = new CamelMessageHandler(producerTemplate);
camelMessageHandler.setEndpointUri("direct:simple");
camelMessageHandler.setExchangePatternExpression(spelExpressionParser.parseExpression("headers.exchangePattern"));
camelMessageHandler.setHeaderMapper(headerMapper);
return camelMessageHandler;
}
对于 Java DSL 流定义,此通道适配器可以使用 Camel 工厂提供的几种变体进行配置:
@Bean
IntegrationFlow camelFlow() {
return f -> f
.handle(Camel.gateway().endpointUri("direct:simple"))
.handle(Camel.route(this::camelRoute))
.handle(Camel.handler().endpointUri("log:com.mycompany.order?level=WARN"));
}
private void camelRoute(RouteBuilder routeBuilder) {
routeBuilder.from("direct:inbound").transform(routeBuilder.simple("${body.toUpperCase()}"));
}