此版本仍在开发中,尚不被认为是稳定的。对于最新的稳定版本,请使用 Spring Integration 6.5.1spring-doc.cadn.net.cn

Apache Camel 支持

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

项目需要此依赖项:spring-doc.cadn.net.cn

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

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

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

为了使开发过程更容易并避免不必要的网络跃点,Apache Camel 提供了一个模块,用于通过消息通道与 Spring Integration 进行通信。 所需要的只是引用MessageChannel从应用程序上下文中发送或使用消息。 当Apache Camel路由是消息流的发起者,并且Spring Integration仅作为解决方案的一部分起支持作用时,这很有效。spring-doc.cadn.net.cn

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

Apache Camel 的出站通道适配器

CamelMessageHandler是一个AbstractReplyProducingMessageHandler实现,并且可以在单向(默认)和请求-回复模式下工作。 它使用org.apache.camel.ProducerTemplate发送(或发送和接收)到org.apache.camel.Endpoint. 交互模式可以通过ExchangePattern选项(可以在运行时通过 SpEL 表达式根据请求消息进行评估)。 目标 Apache Camel 端点可以显式配置,也可以配置为要在运行时评估的 SpEL 表达式。 否则,它会回退到defaultEndpointProducerTemplate. 不是指定端点,而是内联的显式LambdaRouteBuilder例如,可以提供来调用 Spring Integration 中没有通道适配器支持的 Apache Camel 组件。spring-doc.cadn.net.cn

此外,一个HeaderMapper<org.apache.camel.Message>(这CamelHeaderMapper是默认实现),以确定在 Spring Integration 和 Apache Camel 消息之间映射哪些标头。 默认情况下,所有标头都被映射。spring-doc.cadn.net.cn

CamelMessageHandler支持async模式调用ProducerTemplate.asyncSend()并产生一个CompletableFuture用于回复处理(如果有)。spring-doc.cadn.net.cn

exchangeProperties可以通过 SpEL 表达式进行自定义,该表达式必须计算为Map.spring-doc.cadn.net.cn

如果ProducerTemplate未提供,它是通过CamelContext从应用程序上下文中解析的 bean。spring-doc.cadn.net.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 流定义,可以使用Camel厂:spring-doc.cadn.net.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()}"));
}