GH-2873: Preserve mapping order in the router (#2877)
* GH-2873: Preserve mapping order in the router Fixes https://github.com/spring-projects/spring-integration/issues/2873 Sometime it is important to map to most specific exception instead of its super class. * Use `LinkedHashMap` for mapping keys in the `ErrorMessageExceptionTypeRouter`, as well as in its `AbstractMappingMessageRouter` superclass. Since we don't do that internal map modification, there is no reason to worry about concurrent access: we just replace an internal instance atomically with a new `LinkedHashMap` every time we modify a mapping for router **Cherry-pick to 5.1.x** * * Fix `RouterSpec.RouterMappingProvider` to `LinkedHashMap` as well * * Fix `RouterTests` for proper mapping order * Polishing for `AbstractMappingMessageRouter` hierarchy, so we don't use `protected channelMappings` field access any more
This commit is contained in:
committed by
Gary Russell
parent
3fc278688c
commit
23a73fab87
@@ -750,13 +750,12 @@ See <<xml-xpath-routing>>.
|
||||
Spring Integration also provides a special type-based router called `ErrorMessageExceptionTypeRouter` for routing error messages (defined as messages whose `payload` is a `Throwable` instance).
|
||||
`ErrorMessageExceptionTypeRouter` is similar to the `PayloadTypeRouter`.
|
||||
In fact, they are almost identical.
|
||||
The only difference is that, while `PayloadTypeRouter` navigates the instance hierarchy of a payload instance (for example, `payload.getClass().getSuperclass()`) to find the most specific type and channel mappings,
|
||||
the `ErrorMessageExceptionTypeRouter` navigates the hierarchy of 'exception causes' (for example, `payload.getCause()`)
|
||||
to find the most specific `Throwable` type or channel mappings and uses `mappingClass.isInstance(cause)` to match the
|
||||
`cause` to the class or any super class.
|
||||
The only difference is that, while `PayloadTypeRouter` navigates the instance hierarchy of a payload instance (for example, `payload.getClass().getSuperclass()`) to find the most specific type and channel mappings, the `ErrorMessageExceptionTypeRouter` navigates the hierarchy of 'exception causes' (for example, `payload.getCause()`) to find the most specific `Throwable` type or channel mappings and uses `mappingClass.isInstance(cause)` to match the `cause` to the class or any super class.
|
||||
|
||||
NOTE: Since version 4.3 the `ErrorMessageExceptionTypeRouter` loads all mapping classes during the initialization
|
||||
phase to fail-fast for a `ClassNotFoundException`.
|
||||
IMPORTANT: The channel mapping order in this case matters.
|
||||
So, if there is a requirement to get mapping for an `IllegalArgumentException`, but not a `RuntimeException`, the last one must be configured on router first.
|
||||
|
||||
NOTE: Since version 4.3 the `ErrorMessageExceptionTypeRouter` loads all mapping classes during the initialization phase to fail-fast for a `ClassNotFoundException`.
|
||||
|
||||
The following example shows a sample configuration for `ErrorMessageExceptionTypeRouter`:
|
||||
|
||||
|
||||
Reference in New Issue
Block a user