diff --git a/src/docbkx/router.xml b/src/docbkx/router.xml
index 5bb0fa182e..c089a3960b 100644
--- a/src/docbkx/router.xml
+++ b/src/docbkx/router.xml
@@ -201,5 +201,206 @@ public List<String> route(@Header("orderStatus") OrderStatus status)
For routing of XML-based Messages, including XPath support, see .
+
+
+ Dynamic Routers
+
+ So as you can see, Spring Integration provides quite a few different router configurations for most common
+ content-based routing use cases as well as the option of implementing custom routers as POJOs.
+ For example; Payload Type Router provides a simple way to configure a router which computes channels
+ based on the payload type of the incoming Message while Header Value Router provides the
+ same convenience in configuring a router which computes channels based on evaluating the value
+ of a particular Message Header. There is also an expression-based (SpEL) routers where the channel
+ is determined based on evaluating an expression which gives these type of routers some dynamic characteristics.
+
+
+ However these routers share one common attribute - static configuration. Even in the case of
+ expression-based routers, the expression itself is defined as part of the router configuration which means that
+ the same expression operating on the same value will always result in the computation of the same channel
.
+ This is good in most cases since such routes are well defined and therefore predictable. But there are times when we
+ need to change router configurations dynamically so message flows could be routed to a different channel.
+
+ For example:
+
+ You might want to bring down some part of your system for maintenance. So, temporarily you want to re-reroute
+ messages to a different message flow. Or you may want to introduce more granularity to your message flow by adding another
+ route to handle a more concrete type of java.lang.Number (in cases of Payload Type Router).
+
+
+ Unfortunately with static router configuration to accomplish this you'd have to bring down your entire application,
+ change the configuration of the router (change routes) and bring it back up. This is obviously not the solution.
+
+
+
+ Dynamic Router
+
+ pattern describes the mechanisms by which one can change/configure routers dynamically without
+ bringing down your system or individual routers.
+
+
+ Before we get into the specifics of how it is accomplished in Spring Integration lets quickly summarize the
+ typical flow of the router, which consists of 3 simple steps:
+
+
+ Step 1 - Compute channel identifier which is a value calculated by the
+ router once it receives the Message. Typically it is a String or and instance of the actual
+ MessageChannel.
+
+
+ Step 2 - Resolve channel identifier to channel name. We'll describe
+ specifics of this process in a moment.
+
+
+ Step 3 - Resolve channel name to the actual MessageChannel
+
+
+
+
+
+ There is not much that could be done with regard to router dynamics if Step 1 results in the actual instance of the
+ MessageChannel simply because MessageChannel is the final product of any
+ router's job. However, if Step 1 results in channel identifier that is not and instance of MessageChannel,
+ then there are quite a few possibilities to influence the process of calculating what will be the final instance of the Message Channel.
+ Lets look at couple of the examples in the context of the 3 steps mentioned above:
+
+
+ Payload Type Router
+
+
+
+
+
+]]>
+
+
+ Within the context of the Payload Type Router the 3 steps mentioned above would be realized as:
+
+
+ Step 1 - Compute channel identifier which is the fully qualified name of the payload type
+ (e.g., java.lang.String).
+
+
+ Step 2 - Resolve channel identifier to channel name where
+ the result of the previous step is used to select the appropriate value from the payload type mapping
+ defined via mapping element.
+
+
+ Step 3 - Resolve channel name to the actual instance of the
+ MessageChannel where using ChannelResolver router will obtain a
+ reference to a bean (which is hopefully a MessageChannel) identified by the result of the
+ previous step.
+
+
+ In other words each step feeds the next step until thr process completes.
+
+
+ Header Value Router
+
+
+
+
+
+]]>
+
+
+ Similar to the PayloadTypeRouter:
+
+
+ Step 1 - Compute channel identifier which is the value of the header identified by the
+ header-name attribute.
+
+
+ Step 2 - Resolve channel identifier to channel name where
+ the result of the previous step is used to select the appropriate value from the general mapping
+ defined via mapping element.
+
+
+ Step 3 - Resolve channel name to the actual instance of the
+ MessageChannel where using ChannelResolver router will obtain a
+ reference to a bean (which is hopefully a MessageChannel) identified by the result of the
+ previous step.
+
+
+
+
+ The above two configurations of two different router types look almost identical.
+ However if we look at the different configuration of the HeaderValueRouter we clearly see that
+ there is no mapping sub element:
+ ]]>
+ But configuration is still perfectly valid. So the natural question is what about the maping in the Step 2?
+
+
+ What this means is that Step 2 is now an optional step. If mapping is not defined then the channel identifier
+ value computed in Step 1 will automatically be treated as the channel name which will now be resolved to the
+ actual MessageChannel in the Step 3. What it also means is that Step 2 is one of the key steps to
+ provide dynamic characteristics to the routers, since it introduces a process which
+ allows you to change the way 'channel identifier' resolves to 'channel name',
+ thus influencing the process of determining the final instance of the MessageChannel from the initial
+ channel identifier.
+
+ For Example:
+
+ In the above configuration lets assume that the testHeader value is 'kermit' which is now a channel identifier
+ (Step 1). Since there is no mapping in this router, resolving this channel identifier to a channel name
+ (Step 2) is impossible and this channel identifier is now treated as channel name. However what if
+ there was mapping but for a different value, the end result would still be the same and that is:
+ if new value can not be determined through the process of resolving 'channel identifier' to a 'channel name',
+ such 'channel identifier' becomes 'channel name'
+
+
+ So all that is left is for Step 3 to resolve channel name ('kermit') to an actual instance of the
+ MessageChannel identified by this name. That will be done via default
+ ChannelResolver implementation which is BeanFactoryChannelResolver which
+ basically does a bean lookup by the name provided. So now all messages which contain the header/value pair as testHeader=kermit
+ are going to be routed to a 'kermit' MessageChannel.
+
+
+ But what if you want to route these messages to 'simpson' channel? Obviously changing static configuration would work,
+ but would also require bringing your system down. However if you had access to channel identifier map, then you
+ could just introduce a new mapping where header/value pair is now kermit=simpson, thus allowing Step 2 to treat
+ 'kermit' as channel identifier while resolving it to 'simpson' as channel name .
+
+
+ The same obviously applies for PayloadTypeRouter where you can now remap or remove a particular payload type
+ mapping, and every other router including expression-based routers since their computed value
+ will now have a chance to go through Step 2 to be aditionally resolved to the actual channel name.
+
+
+ In Spring Integration 2.0 routers hierarchy underwent major refactoring and now any router that is a subclass of the
+ AbstractMessageRouter (all framework defined routers) is a Dynamic Router simply because
+ channelIdentiferMap is defined at the AbstractMessageRouter with convenient accessors
+ and modifiers exposed as public methods allowing you to change/add/remove router mapping at runtime via JMX (see section section 29) or
+ ControlBus (see section section 29.7) functionality.
+
+
+
+ Control Bus
+
+
+ One of the way to manage the router mappings is through the Control Bus
+ which exposes a Control Channel where you can send
+ control messages to manage and monitor Spring Integration components which includes routers.
+ For more information about the Control Bus see section 29.7. Typically you would send a control message asking to invoke a
+ particular JMX operation on a particular managed component (e.g., router). The two managed operations (methods) that are
+ specific to changing router resolution process are:
+
+
+ public void setChannelMapping(String channelIdentifier, String channelName) -
+ will allow you to add new or modify existing mapping of channel identifier to channel name
+
+
+ public void removeChannelMapping(String channelIdentifier) -
+ will allow you to remove a particular channel mapping, thus disconnecting the relationship between
+ channel identifier and channel name
+
+
+ There are obviously other managed operations, so please refer to an AbstractMessageRouter for more detail
+
+
+ You can also use your favorite JMX client (e.g., JConsole) and use those operations (methods) to change
+ router configuration. For more information on Spring Integration management and monitoring please visit
+ section 29 of this manual.
+
+
\ No newline at end of file