对于最新的稳定版本,请使用 Spring Integration 6.5.1! |
Apache Camel 支持
Spring Integration 提供了一个 API 和配置,用于与在同一应用程序上下文中声明的 Apache Camel 端点进行通信。
您需要将此依赖项包含在您的项目中:
-
Maven
-
Gradle
<dependency>
<groupId>org.springframework.integration</groupId>
<artifactId>spring-integration-camel</artifactId>
<version>6.2.11</version>
</dependency>
compile "org.springframework.integration:spring-integration-camel:6.2.11"
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 端点,并(可选)等待回复。没有入站通道适配器,因为订阅MessageChannel
从 Spring Integration API 和抽象的角度来看,使用 Apache Camel 消息就足够了。
Apache Camel 的出站通道适配器
这CamelMessageHandler
是一个AbstractReplyProducingMessageHandler
实现,并且可以在单向(默认)和请求-回复模式下工作。它使用org.apache.camel.ProducerTemplate
发送(或发送和接收)到org.apache.camel.Endpoint
. 交互模式可以通过ExchangePattern
选项(可以在运行时通过 SpEL 表达式根据请求消息进行评估)。目标 Apache Camel 端点可以显式配置,也可以配置为要在运行时评估的 SpEL 表达式。否则,它会回退到defaultEndpoint
在ProducerTemplate
. 不是指定端点,而是内联的显式LambdaRouteBuilder
例如,调用 Spring Integration 中没有通道适配器支持的 Apache Camel 组件。
此外,一个HeaderMapper<org.apache.camel.Message>
(这CamelHeaderMapper
是默认实现),以确定在 Spring Integration 和 Apache Camel 消息之间映射哪些标头。默认情况下,所有标头都被映射。
这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()}"));
}