1

Spring 統合を使用してルーティング スリップ (EI パターン) を実装しようとしています。私が行った設定は

 @Bean
    @Transformer(inputChannel = "routingServiceChannel")
    public HeaderEnricher headerEnricher() {
        return new HeaderEnricher(Collections.singletonMap(IntegrationMessageHeaderAccessor.ROUTING_SLIP,
                new RoutingSlipHeaderValueMessageProcessor("routingChannel2",                   
                    "routingChannel1")));
    }

したがって、routingServiceChannel に到達すると、routingChannel2 に移動し、次に routingChannel1 に移動します。しかし、私の場合、応答チャネルがないという例外が常にスローされます。出力チャンネルを設定すると、

@Transformer(inputChannel = "routingServiceChannel", outputChannel=""xyzChannel)

次に、routingChannel2 と routingChannel1 に行く代わりに、xyzChannel にルーティングが発生します。

Spring Integration Core でコードをデバッグしたとき、このコードに出くわしました。

クラス AbstractReplyProducingMessageHandler

protected final void handleMessageInternal(Message<?> message) {
        Object result;
        if (this.advisedRequestHandler == null) {
            result = handleRequestMessage(message);
        } else {
            result = doInvokeAdvisedRequestHandler(message);
        }
        if (result != null) {
            sendOutputs(result, message);
        } else if (this.requiresReply) {
            throw new ReplyRequiredException(message, "No reply produced by handler '" + getComponentName()
                    + "', and its 'requiresReply' property is set to true.");
        } else if (logger.isDebugEnabled()) {
            logger.debug("handler '" + this + "' produced no reply for request Message: " + message);
        }
    }

ここで、ハンドル メッセージ メソッドで、routingSlip マップを取得し、それを結果に割り当てます。と

protected void produceOutput(Object reply, Message<?> requestMessage) {
        MessageHeaders requestHeaders = requestMessage.getHeaders();

        Object replyChannel = null;
        if (getOutputChannel() == null) {
            Map<?, ?> routingSlipHeader = requestHeaders.get(IntegrationMessageHeaderAccessor.ROUTING_SLIP, Map.class);
            if (routingSlipHeader != null) {
                Assert.isTrue(routingSlipHeader.size() == 1, "The RoutingSlip header value must be a SingletonMap");
                Object key = routingSlipHeader.keySet().iterator().next();
                Object value = routingSlipHeader.values().iterator().next();
                Assert.isInstanceOf(List.class, key, "The RoutingSlip key must be List");
                Assert.isInstanceOf(Integer.class, value, "The RoutingSlip value must be Integer");
                List<?> routingSlip = (List<?>) key;
                AtomicInteger routingSlipIndex = new AtomicInteger((Integer) value);
                replyChannel = getOutputChannelFromRoutingSlip(reply, requestMessage, routingSlip, routingSlipIndex);
                if (replyChannel != null) {
                    // TODO Migrate to the SF MessageBuilder
                    AbstractIntegrationMessageBuilder<?> builder = null;
                    if (reply instanceof Message) {
                        builder = this.getMessageBuilderFactory().fromMessage((Message<?>) reply);
                    } else if (reply instanceof AbstractIntegrationMessageBuilder) {
                        builder = (AbstractIntegrationMessageBuilder<?>) reply;
                    } else {
                        builder = this.getMessageBuilderFactory().withPayload(reply);
                    }
                    builder.setHeader(IntegrationMessageHeaderAccessor.ROUTING_SLIP,
                            Collections.singletonMap(routingSlip, routingSlipIndex.get()));
                    reply = builder;
                }
            }

            if (replyChannel == null) {
                replyChannel = requestHeaders.getReplyChannel();
            }
        }

        Message<?> replyMessage = createOutputMessage(reply, requestHeaders);
        sendOutput(replyMessage, replyChannel);
    }

応答から routingSlip 構成を取得する代わりに、requestMessage から取得しようとしています。ここで何か不足していますか?設定する必要がある追加の構成はありますか?

4

1 に答える 1

1

件名に注意していただきありがとうございます、ところで!:)

すべて問題ないように見えますが、回覧用紙の要点を見逃しています。

まず、メッセージ用に構成する必要があります。また、Routing Slip は であるため、メッセージのヘッダーに追加するためにheader使用する必要があります。HeaderEnricher

ルーティングは実際には からのダウンストリームで行われ、requestMessageではなくに対して正確に行われreplyます。回覧先は ですHeaderEnricher

もちろん、HeaderEnricherの場合は発生する可能性がありますが。requestMessage

の直後に回覧用紙を調べたい場合は、次のHeaderEnricherように構成する必要があります。

@BridgeTo
@Bean
public MessageChannel xyzChannel() {
    return new DirectChannel();
}

注:ロジック中に使用できる新しいヘッダーはありません。HeaderEnricher下流のみ。ルーティング スリップもその 1 つです。

于 2016-03-23T02:39:12.577 に答える