From 404f2f83e20f1e8910fd7ed844609311b5cd935d Mon Sep 17 00:00:00 2001 From: abilan Date: Mon, 1 May 2023 14:13:03 -0400 Subject: [PATCH 1/3] GH-8583: Add Java & DSL samples into docs Fixes https://github.com/spring-projects/spring-integration/issues/8583 When users jump into docs first thing these days they expect to see a Java DSL sample. --- src/reference/asciidoc/filter.adoc | 41 ++- src/reference/asciidoc/service-activator.adoc | 60 ++++- src/reference/asciidoc/splitter.adoc | 38 ++- src/reference/asciidoc/transformer.adoc | 247 ++++++++++++++++-- 4 files changed, 362 insertions(+), 24 deletions(-) diff --git a/src/reference/asciidoc/filter.adoc b/src/reference/asciidoc/filter.adoc index 76948533e1d..4a8eba35b5b 100644 --- a/src/reference/asciidoc/filter.adoc +++ b/src/reference/asciidoc/filter.adoc @@ -31,11 +31,50 @@ MessageFilter filter = new MessageFilter(someSelector); ---- ==== -In combination with the namespace and SpEL, you can configure powerful filters with very little Java code. +[[filter-dsl]] +==== Configuring a Filter with Java, Groovy and Kotlin DSL + +The `IntegrationFlowBuilder` from Java DSL (used also as a base in Groovy and Kotlin DSL) provides a number of overloaded methods for `filter()` operator. +The mentioned above `MessageSelector` abstraction can be used as a Lambda in a `filter()` definition: + +==== +[source, java, role="primary"] +.Java DSL +---- +@Bean +public IntegrationFlow someFlow() { + return f -> f + .filter((payload) -> !"junk".equals(payload)); +} +---- +[source, kotlin, role="secondary"] +.Kotlin DSL +---- +@Bean +fun someFlow() = + integrationFlow { + filter { it != "junk" } + } +---- +[source, groovy, role="secondary"] +.Groovy DSL +---- +@Bean +someFlow() { + integrationFlow { + filter String, { it != 'junk' } + } +} +---- +==== + +See more information about Java, Kotlin and Groovy DSL in the respective chapters. [[filter-xml]] ==== Configuring a Filter with XML +In combination with the namespace and SpEL, you can configure powerful filters with very little Java code. + You can use the `` element is used to create a message-selecting endpoint. In addition to `input-channel` and `output-channel` attributes, it requires a `ref` attribute. The `ref` can point to a `MessageSelector` implementation, as the following example shows: diff --git a/src/reference/asciidoc/service-activator.adoc b/src/reference/asciidoc/service-activator.adoc index 551b2d39441..fcd6c93d891 100644 --- a/src/reference/asciidoc/service-activator.adoc +++ b/src/reference/asciidoc/service-activator.adoc @@ -10,7 +10,63 @@ As with most of the configuration options described here, the same behavior actu [[service-activator-namespace]] ==== Configuring Service Activator -To create a service activator, use the 'service-activator' element with the 'input-channel' and 'ref' attributes, as the following example shows: +With Java & Annotation configuration, there is just enough to mark respective service method with the `@ServiceActivator` - and the framework calls it when messages are consumed from an input channel: + +==== +[source,java] +---- +public class SomeService { + + @ServiceActivator(inputChannel = "exampleChannel") + public void exampleHandler(SomeData payload) { + ... + } + +} +---- +==== + +See more information in the <<./configuration.adoc#annotations, Annotation Support>>. + +For Java, Groovy or Kotlin DSL, the `.handle()` operator of an `IntegrationFlow` represents a service activator: + +==== +[source, java, role="primary"] +.Java DSL +---- +@Bean +public IntegrationFlow someFlow() { + return IntegrationFlow + .from("exampleChannel") + .handle(someService, "exampleHandler") + .get(); +} +---- +[source, kotlin, role="secondary"] +.Kotlin DSL +---- +@Bean +fun someFlow() = + integrationFlow("exampleChannel") { + handle(someService, "exampleHandler") + } +---- +[source, groovy, role="secondary"] +.Groovy DSL +---- +@Bean +someFlow() { + integrationFlow 'exampleChannel', + { + handle someService, 'exampleHandler' + } +} +---- +==== + +See more information about DSL in respective Java, Groovy and Kotlin chapters. + +To create a service activator with an XML configuration, use the 'service-activator' element with the 'input-channel' and 'ref' attributes, as the following example shows: ==== [source,xml] @@ -59,7 +115,7 @@ If it can be resolved, the message is sent there. If the request message does not have a `replyChannel` header and the `reply` object is a `Message`, its `replyChannel` header is consulted for a target destination. This is the technique used for request-reply messaging in Spring Integration, and it is also an example of the return address pattern. -If your method returns a result and you want to discard it and end the flow, you should configure the `output-channel` to send to a `NullChannel`. +If your method returns a result, and you want to discard it and end the flow, you should configure the `output-channel` to send to a `NullChannel`. For convenience, the framework registers one with the name, `nullChannel`. See <<./channel.adoc#channel-special-channels,Special Channels>> for more information. diff --git a/src/reference/asciidoc/splitter.adoc b/src/reference/asciidoc/splitter.adoc index 3059979ca04..3f3ebf0b217 100644 --- a/src/reference/asciidoc/splitter.adoc +++ b/src/reference/asciidoc/splitter.adoc @@ -69,6 +69,42 @@ Starting with version 5.2, the splitter supports a `discardChannel` option for s In this case there is just no item to iterate for sending to the `outputChannel`. The `null` splitting result remains as an end of flow indicator. +==== Configuring a Splitter with Java, Groovy and Kotlin DSL + +An example of simple splitter based on a `Message` and its iterable payload with DSL configuration: + +==== +[source, java, role="primary"] +.Java DSL +---- +@Bean +public IntegrationFlow someFlow() { + return f -> f.split(Message.class, Message::getPayload); +} +---- +[source, kotlin, role="secondary"] +.Kotlin DSL +---- +@Bean +fun someFlow() = + integrationFlow { + split> { it.payload } + } +---- +[source, groovy, role="secondary"] +.Groovy DSL +---- +@Bean +someFlow() { + integrationFlow { + split Message, { it.payload } + } +} +---- +==== + +See <<./dsl.adoc#java-dsl-splitters,Splitters>> in Java DSL chapter for more information. + ==== Configuring a Splitter with XML A splitter can be configured through XML as follows: @@ -142,4 +178,4 @@ List extractItems(Order order) { ---- ==== -See also <<./handler-advice.adoc#advising-with-annotations,Advising Endpoints Using Annotations>>, <<./dsl.adoc#java-dsl-splitters,Splitters>> and <<./file.adoc#file-splitter, File Splitter>>. +See also <<./handler-advice.adoc#advising-with-annotations,Advising Endpoints Using Annotations>> and <<./file.adoc#file-splitter, File Splitter>>. diff --git a/src/reference/asciidoc/transformer.adoc b/src/reference/asciidoc/transformer.adoc index dff9c18175a..08a18fb1d09 100644 --- a/src/reference/asciidoc/transformer.adoc +++ b/src/reference/asciidoc/transformer.adoc @@ -14,6 +14,66 @@ NOTE: For the sake of maximizing flexibility, Spring does not require XML-based Nevertheless, the framework does provide some convenient transformers for dealing with XML-based payloads if that is indeed the right choice for your application. For more information on those transformers, see <<./xml.adoc#xml,XML Support - Dealing with XML Payloads>>. +==== Configuring a Transformer with Java and other DSLs + +For a simple Java & Annotation configuration, the Spring bean POJO method must be marked with a `@Transformer` annotation and the framework calls it when messages are consumed from an input channel: + +==== +[source,java] +---- +public class SomeService { + + @Transfomer(inputChannel = "transformChannel", outputChannel = "nextServiceChannel") + public OutputData exampleTransformer(InputData payload) { + ... + } + +} +---- +==== + +See more information in the <<./configuration.adoc#annotations, Annotation Support>>. + +For Java, Groovy or Kotlin DSL, the `.transform()` operator of an `IntegrationFlow` represents a transformer endpoint: + +==== +[source, java, role="primary"] +.Java DSL +---- +@Bean +public IntegrationFlow someFlow() { + return IntegrationFlow + .from("transformChannel") + .transform(someService, "exampleTransformer") + .channel("nextServiceChannel") + .get(); +} +---- +[source, kotlin, role="secondary"] +.Kotlin DSL +---- +@Bean +fun someFlow() = + integrationFlow("transformChannel") { + transform(someService, "exampleTransformer") + channel("nextServiceChannel") + } +---- +[source, groovy, role="secondary"] +.Groovy DSL +---- +@Bean +someFlow() { + integrationFlow 'transformChannel', + { + transform someService, 'exampleTransformer' + channel 'nextServiceChannel' + } +} +---- +==== + + [[transformer-namespace]] ==== Configuring a Transformer with XML @@ -83,12 +143,47 @@ Spring Integration provides a few transformer implementations. ===== Object-to-String Transformer -Because it is fairly common to use the `toString()` representation of an `Object`, Spring Integration provides an `ObjectToStringTransformer` whose output is a `Message` with a String `payload`. +Because it is fairly common to use the `toString()` representation of an `Object`, Spring Integration provides an `ObjectToStringTransformer` (see also `Transformers` factory) whose output is a `Message` with a String `payload`. That `String` is the result of invoking the `toString()` operation on the inbound Message's payload. The following example shows how to declare an instance of the object-to-string transformer: ==== -[source,xml] +[source, java, role="primary"] +.Java DSL +---- +@Bean +public IntegrationFlow someFlow() { + return IntegrationFlow + .from("in") + .transform(Transformers.objectToString()) + .channel("out") + .get(); +} +---- +[source, kotlin, role="secondary"] +.Kotlin DSL +---- +@Bean +fun someFlow() = + integrationFlow("in") { + transform(Transformers.objectToString()) + channel("out") + } +---- +[source, groovy, role="secondary"] +.Groovy DSL +---- +@Bean +someFlow() { + integrationFlow 'in', + { + transform Transformers.objectToString() + channel 'out' + } +} +---- +[source, xml, role="secondary"] +.XML ---- ---- @@ -102,8 +197,6 @@ Otherwise, you can provide a custom POJO-based transformer by using the generic TIP: When debugging, this transformer is not typically necessary, since the `logging-channel-adapter` is capable of logging the message payload. See <<./channel.adoc#channel-wiretap,Wire Tap>> for more detail. -[NOTE] -==== The object-to-string transformer is very simple. It invokes `toString()` on the inbound payload. Since Spring Integration 3.0, there are two exceptions to this rule: @@ -114,19 +207,50 @@ The `charset` can be modified by supplying the charset attribute on the transfor For more sophistication (such as selection of the charset dynamically, at runtime), you can use a SpEL expression-based transformer instead, as the following example shows: -[source,xml] +==== +[source, java, role="primary"] +.Java DSL +---- +@Bean +public IntegrationFlow someFlow() { + return IntegrationFlow + .from("in") + .transform("new String(payload, headers['myCharset']") + .channel("out") + .get(); +} +---- +[source, xml, role="secondary"] +.XML ---- + expression="new String(payload, headers['myCharset']" /> ---- ==== If you need to serialize an `Object` to a byte array or deserialize a byte array back into an `Object`, Spring Integration provides symmetrical serialization transformers. These use standard Java serialization by default, but you can provide an implementation of Spring `Serializer` or `Deserializer` strategies by using the `serializer` and `deserializer` attributes, respectively. +See also the `Transformers` factory class. The following example shows to use Spring's serializer and deserializer: ==== -[source,xml] +[source, java, role="primary"] +.Java DSL +---- +@Bean +public IntegrationFlow someFlow() { + return IntegrationFlow + .from("objectsIn") + .transform(Transformers.serializer()) + .channel("bytesOut") + .channel("bytesIn") + .transform(Transformers.deserializer("com.mycom.*", "com.yourcom.*")) + .channel("objectsOut") + .get(); +} +---- +[source, xml, role="secondary"] +.XML ---- @@ -226,10 +350,23 @@ The two classes in the preceding example are transformed to the following `Map`: ---- ==== -To configure these transformers, Spring Integration provides namespace support for Object-to-Map, as the following example shows: +To configure these transformers, Spring Integration provides respective XML component and Java DSL factory: ==== -[source,xml] +[source, java, role="primary"] +.Java DSL +---- +@Bean +public IntegrationFlow someFlow() { + return IntegrationFlow + .from("directInput") + .transform(Transformers.toMap()) + .channel("output") + .get(); +} +---- +[source, xml, role="secondary"] +.XML ---- ---- @@ -238,16 +375,42 @@ To configure these transformers, Spring Integration provides namespace support f You can also set the `flatten` attribute to false, as follows: ==== -[source,xml] +[source, java, role="primary"] +.Java DSL +---- +@Bean +public IntegrationFlow someFlow() { + return IntegrationFlow + .from("directInput") + .transform(Transformers.toMap(false)) + .channel("output") + .get(); +} +---- +[source, xml, role="secondary"] +.XML ---- ---- ==== -Spring Integration provides namespace support for Map-to-Object, as the following example shows: +Spring Integration provides an XML namespace support for Map-to-Object and Java DSL factory, as the following example shows: ==== -[source,xml] +[source, java, role="primary"] +.Java DSL +---- +@Bean +public IntegrationFlow someFlow() { + return IntegrationFlow + .from("input") + .transform(Transformers.fromMap(org.something.Person.class)) + .channel("output") + .get(); +} +---- +[source, xml, role="secondary"] +.XML ---- - ---- +==== NOTE: The 'ref' and 'type' attributes are mutually exclusive. Also, if you use the 'ref' attribute, you must point to a 'prototype' scoped bean. @@ -280,7 +464,20 @@ The `StreamTransformer` transforms `InputStream` payloads to a `byte[]`( or a `S The following example shows how to use the `stream-transformer` element in XML: ==== -[source, xml] +[source, java, role="primary"] +.Java DSL +---- +@Bean +public IntegrationFlow someFlow() { + return IntegrationFlow + .from("input") + .transform(Transformers.fromStream("UTF-8")) + .channel("output") + .get(); +} +---- +[source, xml, role="secondary"] +.XML ---- @@ -318,10 +515,7 @@ The following pair of examples show how to declare them in XML: [source,xml] ---- ----- -[source,xml] ----- ---- @@ -364,7 +558,7 @@ public class ObjectMapperFactory { ---- ==== -The following example shows how to do the same thing in XML +The following example shows how to do the same thing in XML: ==== [source,xml] @@ -546,7 +740,20 @@ The latter is discussed in <<./content-enrichment.adoc#header-enricher,Header En The following example defines a header filter: ==== -[source,xml] +[source, java, role="primary"] +.Java DSL +---- +@Bean +public IntegrationFlow someFlow() { + return IntegrationFlow + .from("inputChannel") + .headerFilter("lastName", "state") + .channel("outputChannel") + .get(); +} +---- +[source, xml, role="secondary"] +.XML ---- From 3701d49b1c110645a494fc679fc04cb5c7dcec55 Mon Sep 17 00:00:00 2001 From: Artem Bilan Date: Mon, 1 May 2023 16:18:19 -0400 Subject: [PATCH 2/3] Fix language in Docs Co-authored-by: Gary Russell --- src/reference/asciidoc/filter.adoc | 8 ++++---- src/reference/asciidoc/service-activator.adoc | 8 ++++---- src/reference/asciidoc/splitter.adoc | 2 +- src/reference/asciidoc/transformer.adoc | 8 ++++---- 4 files changed, 13 insertions(+), 13 deletions(-) diff --git a/src/reference/asciidoc/filter.adoc b/src/reference/asciidoc/filter.adoc index 4a8eba35b5b..47660f90313 100644 --- a/src/reference/asciidoc/filter.adoc +++ b/src/reference/asciidoc/filter.adoc @@ -32,10 +32,10 @@ MessageFilter filter = new MessageFilter(someSelector); ==== [[filter-dsl]] -==== Configuring a Filter with Java, Groovy and Kotlin DSL +==== Configuring a Filter with Java, Groovy and Kotlin DSLs -The `IntegrationFlowBuilder` from Java DSL (used also as a base in Groovy and Kotlin DSL) provides a number of overloaded methods for `filter()` operator. -The mentioned above `MessageSelector` abstraction can be used as a Lambda in a `filter()` definition: +The `IntegrationFlowBuilder` provided by the Java DSL (which is also used as a base for the Groovy and Kotlin DSLs) provides a number of overloaded methods for the `filter()` operator. +The `MessageSelector` abstraction mentioned above can be used as a Lambda in a `filter()` definition: ==== [source, java, role="primary"] @@ -68,7 +68,7 @@ someFlow() { ---- ==== -See more information about Java, Kotlin and Groovy DSL in the respective chapters. +See more information about Java, Kotlin and Groovy DSLs in the respective chapters. [[filter-xml]] ==== Configuring a Filter with XML diff --git a/src/reference/asciidoc/service-activator.adoc b/src/reference/asciidoc/service-activator.adoc index fcd6c93d891..bbf1821ea5e 100644 --- a/src/reference/asciidoc/service-activator.adoc +++ b/src/reference/asciidoc/service-activator.adoc @@ -10,7 +10,7 @@ As with most of the configuration options described here, the same behavior actu [[service-activator-namespace]] ==== Configuring Service Activator -With Java & Annotation configuration, there is just enough to mark respective service method with the `@ServiceActivator` - and the framework calls it when messages are consumed from an input channel: +With Java & Annotation configuration, it is sufficient to mark the respective service method with the `@ServiceActivator` annotation - and the framework calls it when messages are consumed from an input channel: ==== [source,java] @@ -28,7 +28,7 @@ public class SomeService { See more information in the <<./configuration.adoc#annotations, Annotation Support>>. -For Java, Groovy or Kotlin DSL, the `.handle()` operator of an `IntegrationFlow` represents a service activator: +For Java, Groovy or Kotlin DSLs, the `.handle()` operator of an `IntegrationFlow` represents a service activator: ==== [source, java, role="primary"] @@ -64,9 +64,9 @@ someFlow() { ---- ==== -See more information about DSL in respective Java, Groovy and Kotlin chapters. +See more information about the DSLs in the respective Java, Groovy and Kotlin chapters. -To create a service activator with an XML configuration, use the 'service-activator' element with the 'input-channel' and 'ref' attributes, as the following example shows: +To create a service activator when using XML configuration, use the 'service-activator' element with the 'input-channel' and 'ref' attributes, as the following example shows: ==== [source,xml] diff --git a/src/reference/asciidoc/splitter.adoc b/src/reference/asciidoc/splitter.adoc index 3f3ebf0b217..1bfbe6548a5 100644 --- a/src/reference/asciidoc/splitter.adoc +++ b/src/reference/asciidoc/splitter.adoc @@ -69,7 +69,7 @@ Starting with version 5.2, the splitter supports a `discardChannel` option for s In this case there is just no item to iterate for sending to the `outputChannel`. The `null` splitting result remains as an end of flow indicator. -==== Configuring a Splitter with Java, Groovy and Kotlin DSL +==== Configuring a Splitter with Java, Groovy and Kotlin DSLs An example of simple splitter based on a `Message` and its iterable payload with DSL configuration: diff --git a/src/reference/asciidoc/transformer.adoc b/src/reference/asciidoc/transformer.adoc index 08a18fb1d09..3d238f4c3cd 100644 --- a/src/reference/asciidoc/transformer.adoc +++ b/src/reference/asciidoc/transformer.adoc @@ -16,7 +16,7 @@ For more information on those transformers, see <<./xml.adoc#xml,XML Support - D ==== Configuring a Transformer with Java and other DSLs -For a simple Java & Annotation configuration, the Spring bean POJO method must be marked with a `@Transformer` annotation and the framework calls it when messages are consumed from an input channel: +For simple Java & Annotation configuration, the Spring bean POJO method must be marked with a `@Transformer` annotation and the framework calls it when messages are consumed from an input channel: ==== [source,java] @@ -34,7 +34,7 @@ public class SomeService { See more information in the <<./configuration.adoc#annotations, Annotation Support>>. -For Java, Groovy or Kotlin DSL, the `.transform()` operator of an `IntegrationFlow` represents a transformer endpoint: +For Java, Groovy or Kotlin DSLs, the `.transform()` operator of an `IntegrationFlow` represents a transformer endpoint: ==== [source, java, role="primary"] @@ -143,7 +143,7 @@ Spring Integration provides a few transformer implementations. ===== Object-to-String Transformer -Because it is fairly common to use the `toString()` representation of an `Object`, Spring Integration provides an `ObjectToStringTransformer` (see also `Transformers` factory) whose output is a `Message` with a String `payload`. +Because it is fairly common to use the `toString()` representation of an `Object`, Spring Integration provides an `ObjectToStringTransformer` (see also the `Transformers` factory) where the output is a `Message` with a String `payload`. That `String` is the result of invoking the `toString()` operation on the inbound Message's payload. The following example shows how to declare an instance of the object-to-string transformer: @@ -394,7 +394,7 @@ public IntegrationFlow someFlow() { ---- ==== -Spring Integration provides an XML namespace support for Map-to-Object and Java DSL factory, as the following example shows: +Spring Integration provides XML namespace support for Map-to-Object and the Java DSL factory has the `fromMap()` method, as the following example shows: ==== [source, java, role="primary"] From 59b42c9335b4b33f25629974bca1702d8952a659 Mon Sep 17 00:00:00 2001 From: abilan Date: Mon, 1 May 2023 16:38:19 -0400 Subject: [PATCH 3/3] * Improve `router.adoc` for DSL samples * Add links to DSL chapters --- src/reference/asciidoc/filter.adoc | 6 ++- src/reference/asciidoc/router.adoc | 47 +++++++++++++++++-- src/reference/asciidoc/service-activator.adoc | 6 ++- src/reference/asciidoc/splitter.adoc | 6 ++- src/reference/asciidoc/transformer.adoc | 5 ++ 5 files changed, 64 insertions(+), 6 deletions(-) diff --git a/src/reference/asciidoc/filter.adoc b/src/reference/asciidoc/filter.adoc index 47660f90313..2cdbc241f6c 100644 --- a/src/reference/asciidoc/filter.adoc +++ b/src/reference/asciidoc/filter.adoc @@ -68,7 +68,11 @@ someFlow() { ---- ==== -See more information about Java, Kotlin and Groovy DSLs in the respective chapters. +See more information about DSLs in the respective chapters: + +* <<./dsl.adoc#java-dsl,Java DSL>> +* <<./kotlin-dsl.adoc#kotlin-dsl,Kotlin DSL>> +* <<./groovy-dsl.adoc#groovy-dsl,Groovy DSL>> [[filter-xml]] ==== Configuring a Filter with XML diff --git a/src/reference/asciidoc/router.adoc b/src/reference/asciidoc/router.adoc index 94889a986f7..bcaff178bea 100644 --- a/src/reference/asciidoc/router.adoc +++ b/src/reference/asciidoc/router.adoc @@ -739,7 +739,7 @@ It is a "`registering an interest in something that is part of the message`" use Because of the runtime management operation for the ``, it can be configured without any `` from the start. In this case, the behavior of `RecipientListRouter` is the same when there is no one matching recipient for the message. If `defaultOutputChannel` is configured, the message is sent there. -Otherwise the `MessageDeliveryException` is thrown. +Otherwise, the `MessageDeliveryException` is thrown. [[router-implementations-xpath-router]] ===== XPath Router @@ -762,7 +762,47 @@ NOTE: Since version 4.3 the `ErrorMessageExceptionTypeRouter` loads all mapping The following example shows a sample configuration for `ErrorMessageExceptionTypeRouter`: -[source,xml] +==== +[source, java, role="primary"] +.Java DSL +---- +@Bean +public IntegrationFlow someFlow() { + return f -> f + .routeByException(r -> r + .channelMapping(IllegalArgumentException.class, "illegalChannel") + .channelMapping(NullPointerException.class, "npeChannel") + .defaultOutputChannel("defaultChannel")); +} +---- +[source, kotlin, role="secondary"] +.Kotlin DSL +---- +@Bean +fun someFlow() = + integrationFlow { + routeByException { + channelMapping(IllegalArgumentException::class.java, "illegalChannel") + channelMapping(NullPointerException::class.java, "npeChannel") + defaultOutputChannel("defaultChannel") + } + } +---- +[source, groovy, role="secondary"] +.Groovy DSL +---- +@Bean +someFlow() { + integrationFlow { + routeByException { + channelMapping IllegalArgumentException, 'illegalChannel' + channelMapping NullPointerException, 'npeChannel' + defaultOutputChannel 'defaultChannel' + } + } +} +---- +[source, xml, role="secondary"] ---- @@ -775,6 +815,7 @@ The following example shows a sample configuration for `ErrorMessageExceptionTyp ---- +==== [[router-namespace]] ==== Configuring a Generic Router @@ -1115,7 +1156,7 @@ That basically involves a bean lookup for the provided name. Now all messages that contain the header-value pair as `testHeader=kermit` are going to be routed to a `MessageChannel` whose bean name (its `id`) is 'kermit'. But what if you want to route these messages to the 'simpson' channel? Obviously changing a static configuration works, but doing so also requires bringing your system down. -However, if you have had an access to the channel identifier map, you could introduce a new mapping where the header-value pair is now `kermit=simpson`, thus letting the second step treat 'kermit' as a channel identifier while resolving it to 'simpson' as the channel name. +However, if you have had access to the channel identifier map, you could introduce a new mapping where the header-value pair is now `kermit=simpson`, thus letting the second step treat 'kermit' as a channel identifier while resolving it to 'simpson' as the channel name. The same obviously applies for `PayloadTypeRouter`, where you can now remap or remove a particular payload type mapping. In fact, it applies to every other router, including expression-based routers, since their computed values now have a chance to go through the second step to be resolved to the actual `channel name`. diff --git a/src/reference/asciidoc/service-activator.adoc b/src/reference/asciidoc/service-activator.adoc index bbf1821ea5e..d8f84509e51 100644 --- a/src/reference/asciidoc/service-activator.adoc +++ b/src/reference/asciidoc/service-activator.adoc @@ -64,7 +64,11 @@ someFlow() { ---- ==== -See more information about the DSLs in the respective Java, Groovy and Kotlin chapters. +See more information about the DSLs in the respective chapters: + +* <<./dsl.adoc#java-dsl,Java DSL>> +* <<./kotlin-dsl.adoc#kotlin-dsl,Kotlin DSL>> +* <<./groovy-dsl.adoc#groovy-dsl,Groovy DSL>> To create a service activator when using XML configuration, use the 'service-activator' element with the 'input-channel' and 'ref' attributes, as the following example shows: diff --git a/src/reference/asciidoc/splitter.adoc b/src/reference/asciidoc/splitter.adoc index 1bfbe6548a5..17d3f53ebd1 100644 --- a/src/reference/asciidoc/splitter.adoc +++ b/src/reference/asciidoc/splitter.adoc @@ -103,7 +103,11 @@ someFlow() { ---- ==== -See <<./dsl.adoc#java-dsl-splitters,Splitters>> in Java DSL chapter for more information. +See more information about the DSLs in the respective chapters: + +* <<./dsl.adoc#java-dsl,Java DSL>> +* <<./kotlin-dsl.adoc#kotlin-dsl,Kotlin DSL>> +* <<./groovy-dsl.adoc#groovy-dsl,Groovy DSL>> ==== Configuring a Splitter with XML diff --git a/src/reference/asciidoc/transformer.adoc b/src/reference/asciidoc/transformer.adoc index 3d238f4c3cd..9266e1fda3f 100644 --- a/src/reference/asciidoc/transformer.adoc +++ b/src/reference/asciidoc/transformer.adoc @@ -73,6 +73,11 @@ someFlow() { ---- ==== +See more information about the DSLs in the respective chapters: + +* <<./dsl.adoc#java-dsl,Java DSL>> +* <<./kotlin-dsl.adoc#kotlin-dsl,Kotlin DSL>> +* <<./groovy-dsl.adoc#groovy-dsl,Groovy DSL>> [[transformer-namespace]] ==== Configuring a Transformer with XML