两个HeaderValueRouters采用相同的配置

时间:2017-05-22 15:50:36

标签: spring spring-integration

在我的项目中,我使用Spring Integration。我有以下配置。

我首先使用HeaderValueRouter,如下所示:(它在某个链中)

<int:header-value-router id="router1" header-name="SOME_HEADER"
                         default-output-channel="channelA">
<int:mapping value="a" channel="channelA" />
<int:mapping value="b" channel="channelB" />
<int:mapping value="c" channel="channelC" />
...

现在让我们说Spring Integration将我的消息路由到频道 channelA

在这个频道中,由于我从路由获得的信息,我再次丰富了标题。看起来像这样:(它也在一些链中)

<int:header-value-router id="router2" header-name="SOME_HEADER_2"
                         default-output-channel="channelD">
<int:mapping value="d" channel="channelD" />
<int:mapping value="e" channel="channelE" />
<int:mapping value="f" channel="channelF" />
...

但是会发生的是它在第二个HeaderValueRouter期间没有正确路由。它搜索名为'd'的bean,而不是寻找频道'channelD'。

  

DestinationResolutionException:无法在BeanFactory中查找名为“d”的MessageChannel

我调试了它,发现在HeaderValueRouter的Parent类中,它是AbstractMappingMessageRouter,在其地图上,包含通道的映射,只有第一个映射的通道:“channelA”,“channelB”,“channelC”。

奇怪的是,这两个headerValueRouters在这个地图上都有相同的值,即使这两个是具有不同映射的不同对象。

他们有不同的ID和不同的标题,但他们在父类中使用相同的地图。

SI是否在开头使用相同的映射构建HeaderValueRouter,或者是什么?

它是如何运作的?

编辑:

以下是更多配置,我可以安全地提供尽可能多的信息:

<int-jms:message-driven-channel-adapter
         (some JMS config)
/>

<int:channel id="splitterTask" />

<int:chain id="splitterChain" input-channel="splitterTask">

    <int:header-enricher>
        <int:header name="MODULE" value="splitter" overwrite="true"/>
    </int:header-enricher>

    <int:service-activator ref="someService" method="putMdc"/>

    <int:service-activator ref="someService2" method="persist" />

    <int:header-value-router
            header-name="REQUEST_TYPE"
            default-output-channel="channelA">
        <int:mapping value="a" channel="channelA" />
        <int:mapping value="b" channel="channelB" />
        <int:mapping value="c" channel="channelC" />
        <int:mapping value="special" channel="channelSpecial" />
    </int:header-value-router>

</int:chain>

<int:channel id="channelA" />

...

<int:channel id="channelB" />

...

<int:channel id="channelC" />

...

<!-- again, headers -->
<int:channel id="channelSpecial" />

<int-xml:xpath-expression (some xpath config)/>


<int:chain id="someChain" input-channel="channelSpecial">

    <int-xml:xpath-header-enricher>
        <int-xml:header name="TEMPLATE" xpath-expression-ref="exp"/>
    </int-xml:xpath-header-enricher>

    <int:header-enricher>
        <int:header name="REQUEST_TYPE" ref="some_bean" method="getRequestType" overwrite="true" />
    </int:header-enricher>

    <int:header-value-router
            header-name="REQUEST_TYPE"
            default-output-channel="channelD" >
        <int:mapping value="d" channel="channelD" />
        <int:mapping value="e" channel="channelE" />
        <int:mapping value="f" channel="channelF" />
    </int:header-value-router>

</int:chain>

EDIT2:

我在使用SpringBoot和SI的新项目中检查了它,是的,它确实有效,但我忘了说它部署在WildFly 10上。我认为重建这个大背景的确切环境几乎是不可能的它的。我会尝试。如果我成功了,我会告诉你的。

1 个答案:

答案 0 :(得分:1)

适合我:

<chain input-channel="routingInput">
    <header-value-router id="router1" header-name="SOME_HEADER"
                         default-output-channel="channelA">
        <mapping value="a" channel="channelA"/>
        <mapping value="b" channel="channelB"/>
        <mapping value="c" channel="channelC"/>
    </header-value-router>
</chain>

<chain input-channel="channelA">
    <header-value-router id="router2" header-name="SOME_HEADER_2"
                             default-output-channel="channelD">
        <mapping value="d" channel="channelD" />
        <mapping value="e" channel="channelE" />
        <mapping value="f" channel="channelF" />
    </header-value-router>
</chain>

<channel id="channelD">
    <queue/>
</channel>
@Autowired
private MessageChannel routingInput;

@Autowired
private PollableChannel channelD;

@Test
public void testHeaderValueRouter() {
    this.routingInput.send(
            MessageBuilder.withPayload("foo")
                    .setHeader("SOME_HEADER", "a")
                    .setHeader("SOME_HEADER_2", "d")
                    .build());

    assertNotNull(this.channelD.receive(10_000));
}

如果您能够从我们这边分享类似的完全有用的配置进行测试,那就太棒了。