From 610ad7e0e16262dc1bdc4c781f5fb6043eba67d1 Mon Sep 17 00:00:00 2001 From: Gary Russell Date: Thu, 30 Mar 2017 15:18:22 -0400 Subject: [PATCH] JavaConfig/DSL Docs for Routers (Part 2) (#2104) * JavaConfig/DSL Docs for Routers (Part 2) Add String Expression ctor to `ExpressionEvaluatingRouter`. * Polishing - PR Comments --- .../router/ExpressionEvaluatingRouter.java | 14 ++- src/reference/asciidoc/router.adoc | 89 ++++++++++++++++++- 2 files changed, 99 insertions(+), 4 deletions(-) diff --git a/spring-integration-core/src/main/java/org/springframework/integration/router/ExpressionEvaluatingRouter.java b/spring-integration-core/src/main/java/org/springframework/integration/router/ExpressionEvaluatingRouter.java index c20905c4b4..05b8bce240 100644 --- a/spring-integration-core/src/main/java/org/springframework/integration/router/ExpressionEvaluatingRouter.java +++ b/spring-integration-core/src/main/java/org/springframework/integration/router/ExpressionEvaluatingRouter.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2016 the original author or authors. + * Copyright 2002-2017 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -30,6 +30,18 @@ import org.springframework.integration.handler.ExpressionEvaluatingMessageProces */ public class ExpressionEvaluatingRouter extends AbstractMessageProcessingRouter { + /** + * Construct an instance by parsing the supplied expression string. + * @param expressionString the expression string. + */ + public ExpressionEvaluatingRouter(String expressionString) { + this(EXPRESSION_PARSER.parseExpression(expressionString)); + } + + /** + * Construct an instance with the supplied {@link Expression}. + * @param expression the expression. + */ public ExpressionEvaluatingRouter(Expression expression) { super(new ExpressionEvaluatingMessageProcessor(expression)); setPrimaryExpression(expression); diff --git a/src/reference/asciidoc/router.adoc b/src/reference/asciidoc/router.adoc index 9ced017867..106903ba29 100644 --- a/src/reference/asciidoc/router.adoc +++ b/src/reference/asciidoc/router.adoc @@ -805,7 +805,8 @@ public IntegrationFlow routerFlow() { .ignoreSendFailures(true) .recipient("channel1") .recipient("channel2") - .recipient("channel3"), c -> c.sendTimeout(1_234L)) + .recipient("channel3") + .sendTimeout(1_234L)) .get(); } ---- @@ -867,7 +868,7 @@ In this case the behaviour of `RecipientListRouter` is the same, when there is n ===== XPath Router The XPath Router is part of the XML Module. -As such, please read chapter _<>_ +See _<>_. [[router-implementations-exception-router]] ===== Routing and Error handling @@ -900,7 +901,7 @@ Below is a sample configuration for `ErrorMessageExceptionTypeRouter`. ---- [[router-namespace]] -==== Configuring (Generic) Router +==== Configuring a Generic Router ===== Configuring a Content Based Router with XML @@ -947,6 +948,58 @@ In this case, each "ref" must be to a separate bean instance (or a `prototype`-s However, this optimization only applies if you don't provide any router-specific attributes in the router XML definition. If you inadvertently reference the same message handler from multiple beans, you will get a configuration exception. +The equivalent router, using Java Configuration: + +[source, java] +---- +@Bean +@Router(inputChannel = "routingChannel") +public AbstractMessageRouter myCustomRouter() { + return new AbstractMessageRouter() { + + @Override + protected Collection determineTargetChannels(Message message) { + return // determine channel(s) for message + } + + }; +} +---- + +The equivalent router, using the Java DSL: + +[source, java] +---- +@Bean +public IntegrationFlow routerFlow() { + return IntegrationFlows.from("routingChannel") + .route(myCustomRouter()) + .get(); +} + +public AbstractMessageRouter myCustomRouter() { + return new AbstractMessageRouter() { + + @Override + protected Collection determineTargetChannels(Message message) { + return // determine channel(s) for message + } + + }; +} +---- + +or, if you can route on just some message payload data: + +[source, java] +---- +@Bean +public IntegrationFlow routerFlow() { + return IntegrationFlows.from("routingChannel") + .route(String.class, p -> p.contains("foo") ? "fooChannel" : "barChannel") + .get(); +} +---- _Routers and the Spring Expression Language (SpEL)_ @@ -968,6 +1021,36 @@ Generally a SpEL expression is evaluated and the result is mapped to a channel: ---- +The equivalent router, using Java Configuration: + +[source, java] +---- +@Router(inputChannel = "routingChannel") +@Bean +public ExpressionEvaluatingRouter router() { + ExpressionEvaluatingRouter router = new ExpressionEvaluatingRouter("payload.paymentType"); + router.setChannelMapping("CASH", "cashPaymentChannel"); + router.setChannelMapping("CREDIT", "authorizePaymentChannel"); + router.setChannelMapping("DEBIT", "authorizePaymentChannel"); + return router; +} +---- + +The equivalent router, using the Java DSL: + +[source, java] +---- +@Bean +public IntegrationFlow routerFlow() { + return IntegrationFlows.from("routingChannel") + .route("payload.paymentType", r -> r + .channelMapping("CASH", "cashPaymentChannel") + .channelMapping("CREDIT", "authorizePaymentChannel") + .channelMapping("DEBIT", "authorizePaymentChannel")) + .get(); +} +---- + To simplify things even more, the SpEL expression may evaluate to a channel name: [source,xml]