Few notes as to what is being addressed as part of this refactoring
The goal is to unify router hierarchy to make it more consistent and make routers dynamic (see Dynamic Router pattern http://www.eaipatterns.com/DynamicRouter.html)
- Define ChannelResolver(CR) at the base AbstractMessageRouter. Default implementation of CR is going to be BeanFactoryChannelResolver. Remove MapBasedChannelResover. Later on we can add additional ChannelResolver implementations to optimize resolution process (e.g., CachingChanelResolver that could maintain a map of resolved channels with a refresh functionality)
- Define ChannelIdentifierMap<String, String> at the base AbstractMessageRouter and expose JMX friendly accessors/modifiers to change mappings at runtime.
The routing flow:
Initialization - If mapping is provided (e.g., PayloadTypeRouter - requires, HeaderValueRouter - optional) create channel identifier map as Map<String populating it with mapping data.
Runtime - 3 steps: 1) Compute channelIndicator. 2) Determine channelName (if mapping exists, get the channelName otherwise channelIndicator is the channelName), 3)Resolve channelName to the actual MessageChannel by delegating to ChannelResolver.
AbstractSingleChannelRouter is no longer needed.
Make PayloadTypeRuter and ErrorMessageExceptionTypeRouter more flexible with regard to dealing with payload types that might not have been available to the SI configuration during the compile time to accommodate scenarios where a particular payload type might have been loaded by a different Class Loader which is very common in the distributed, multi-class loader environment such as OSGi or even cross ApplicationContext message exchanges. Withe the state of the current refactoring, this functionality has already been implemented.
However one must be aware, that although iterating through payload type hierarchy for the type that is not visible to a current Class Loader is simple and doable, the payload type names that are entered into channelIdentifierMap are not pre-validated. They are just String values that have fully qualified class name - the name which will be compared to the type names during the introspecting the actual payload types. So the bottom line it is String.equals comparison.