此版本仍在开发中,尚未被视为稳定版本。对于最新的稳定版本,请使用 Spring Integration 6.3.4spring-doc.cn

此版本仍在开发中,尚未被视为稳定版本。对于最新的稳定版本,请使用 Spring Integration 6.3.4spring-doc.cn

Spring 集成提供了一个 API 和配置,用于与在同一应用程序上下文中声明的 Apache Camel 端点进行通信。spring-doc.cn

您需要将此依赖项包含在您的项目中:spring-doc.cn

<dependency>
    <groupId>org.springframework.integration</groupId>
    <artifactId>spring-integration-camel</artifactId>
    <version>6.3.5-SNAPSHOT</version>
</dependency>
compile "org.springframework.integration:spring-integration-camel:6.3.5-SNAPSHOT"

Spring 集成和 Apache Camel 实现了企业集成模式,并提供了一种方便的方式来组合它们,但是这些项目使用不同的方法来实现它们的 API 和抽象。 Spring 集成完全依赖于 Spring Core 中的依赖注入容器。 它使用许多其他 Spring 项目(Spring Data、Spring AMQP、Spring for Apache Kafka 等)来实现其通道适配器。 它还使用抽象作为一等公民,开发人员在编写集成流时需要注意这一点。 另一方面,Apache Camel 没有提供消息通道的一等公民抽象,并提议通过内部交换来组合其路由,对 API 隐藏。 此外,它还需要一些额外的依赖项和配置才能在 Spring 应用程序中使用。MessageChannelspring-doc.cn

即使最终的企业集成解决方案如何实现其部分并不重要,但会考虑开发人员体验和高生产力。 因此,开发人员可能会出于多种原因选择其中一个框架而不是另一个框架,或者如果某些目标系统支持存在差距,则同时选择两者。 Spring 集成和 Apache Camel 应用程序可以通过许多外部协议相互交互,它们为其实现了通道适配器。 例如,Spring 集成流可能会将记录发布到 Apache Kafka 主题,该主题由消费者端的 Apache Camel 端点使用。 或者,Apache Camel 路由可以将数据写入 SFTP 文件该目录,该文件由 Spring 集成的 SFTP 入站通道适配器轮询。 或者,在同一个 Spring 应用程序上下文中,它们可以通过抽象进行通信。ApplicationEventspring-doc.cn

为了简化开发过程并避免不必要的网络跳跃,Apache Camel 提供了一个模块,通过消息通道与 Spring 集成进行通信。 所需要做的就是从应用程序上下文中引用 a 来发送或使用消息。 当 Apache Camel 路由是消息流的发起者,而 Spring 集成仅作为解决方案的一部分扮演支持角色时,这效果很好。MessageChannelspring-doc.cn

为了获得类似的开发人员体验,Spring 集成现在提供了一个通道适配器来调用 Apache Camel 端点,并可选择等待回复。 没有入站通道适配器,因为从 Spring 集成 API 和抽象的角度来看,订阅用于使用 Apache Camel 消息的 a 就足够了。MessageChannelspring-doc.cn

Apache Camel 的出站通道适配器

这是一个实现,可以在 one-way (default) 和 request-reply 模式下工作。 它使用 an 将 发送 (或发送和接收) 到 . 交互模式可以由选项控制(可以在运行时通过 SPEL 表达式根据请求消息进行评估)。 目标 Apache Camel 终端节点可以显式配置,也可以配置为要在运行时评估的 SpEL 表达式。 否则,它将回退到 . 可以提供内联的显式,而不是指定端点,例如,调用 Spring 集成中没有通道适配器支持的 Apache Camel 组件。CamelMessageHandlerAbstractReplyProducingMessageHandlerorg.apache.camel.ProducerTemplateorg.apache.camel.EndpointExchangePatterndefaultEndpointProducerTemplateLambdaRouteBuilderspring-doc.cn

此外,可以提供一个(这是默认实现),以确定在 Spring 集成和 Apache Camel 消息之间映射哪些 Headers。 默认情况下,所有标头都已映射。HeaderMapper<org.apache.camel.Message>CamelHeaderMapperspring-doc.cn

支持模式调用和生成 for reply 处理(如果有)。CamelMessageHandlerasyncProducerTemplate.asyncSend()CompletableFuturespring-doc.cn

可以通过 SpEL 表达式进行自定义,该表达式的计算结果必须为 .exchangePropertiesMapspring-doc.cn

如果未提供 a,则通过从应用程序上下文解析的 bean 创建它。ProducerTemplateCamelContextspring-doc.cn

@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 流定义,可以使用工厂提供的一些变体来配置此通道适配器:Camelspring-doc.cn

@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()}"));
}