Spring 集成 - 如何使用 Kotlin DSL 基于 header 值进行路由

Spring Integration - how to route based on a header value using the Kotlin DSL

假设我有一个 header 上面有一个名为“count”的 属性,我该如何根据该值进行路由?

在 Kotlin DSL 中有路由功能,但我不确定如何将其配置为 HeaderValueRouter

文档对 Java DSL 进行了说明,但我不清楚如何在路由器块中获取 headers。

有人有示例吗(Kotlin 和 Java DSL)?

Spring Integration natively provides specialized router types, including:

HeaderValueRouter

PayloadTypeRouter

ExceptionTypeRouter

RecipientListRouter

XPathRouter

As with many other DSL IntegrationFlowBuilder EIP methods, the route() method can apply any AbstractMessageRouter implementation or, for convenience, a String as a SpEL expression or a ref-method pair. In addition, you can configure route() with a lambda and use a lambda for a Consumer<RouterSpec>.

这是一个单元测试,演示了如何使用 Kotlin DSL 实现您的请求:

@SpringJUnitConfig
@DirtiesContext
class RouterDslTests {

    @Autowired
    @Qualifier("routeByHeader.input")
    private lateinit var routeByHeaderInputChannel: MessageChannel

    @Autowired
    private lateinit var fooChannel: PollableChannel

    @Autowired
    private lateinit var barChannel: PollableChannel

    @Test
    fun `route by header`() {
        var message = MessageBuilder.withPayload("test1")
            .setHeader("my_route", "foo")
            .build()

        this.routeByHeaderInputChannel.send(message)

        var receive = this.fooChannel.receive(10_000)
        var payload = receive?.payload
        assertThat(payload)
            .isNotNull()
            .isEqualTo("test1")

        message = MessageBuilder.withPayload("test2")
            .setHeader("my_route", "bar")
            .build()

        this.routeByHeaderInputChannel.send(message)

        receive = this.barChannel.receive(10_000)
        payload = receive?.payload
        assertThat(payload)
            .isNotNull()
            .isEqualTo("test2")
    }

    @Configuration
    @EnableIntegration
    class Config {

        @Bean
        fun routeByHeader() =
            integrationFlow {
                route<Message<*>, String>({ it.headers["my_route"].toString() }) {
                    suffix("Channel")
                }
            }

        @Bean
        fun fooChannel() = QueueChannel()

        @Bean
        fun barChannel() = QueueChannel()
    }

}

您只需要执行一个 route() 函数来处理整个 Message 作为输入。然后你可以在 lambda 中访问它的 headers。

Kotlin DSL 文档中可能没有解释,但 Java DSL 中有一些内容:https://docs.spring.io/spring-integration/docs/current/reference/html/dsl.html#java-dsl-class-cast