Custom Message Processors
The interface you implement or abstract class you extend will depend what you want your custom message processor to do:
Message observers do not mutate the message neither do they determine which Message Processor should be invoked next. The easiest way to implement a message observer is to extend AbstractMessageObserver and implementing the abstract observe method.
Example usage: logging, notifications and statistics etc.
Any MessageProcessor can mutate the message as required. If the Message Processor only mutates the message and is not concerned with determining how the message flow continues, then it makes most sense to implement MessageProcessor rather than the InterceptingMessageProcoessor or MessageRouter interfaces.
Example usage: transformers
Sometime you may need to intercept message flow in order to add some level of indirection to the flow by wrapping the next Message Processor or invoking the next message processor in a particular way. I introduced the InterceptingMessageProcessor in the last blog post and this is what we’ll use, but the easiest way to implement a message processor that intercepts flow is by extending AbstractInterceptingMessageProcessor. You still need to implement process but all the rest of the plumbing is done for you and you just need to call processNext when you want to invoke the next MessageProcessor. Example Usage: exception handling, transactions and asynchronous invocation.
In the same way that we may want to intercept the message flow for any of the reason above often you may want to intercept the message flow with the single purpose of filtering, that is to determine if a particular message should continue onto the next message processor or not. You can also implement extend AbstractInterceptingMessageProcessor for this but. If the acceptance criteria can be expressed through the use of a Filter then you can simple use the MessageFilter otherwise you can extend AbstractFilteringMessageProcessor and implement the abstract accept method.
Example Usage: all message payload filters, idempotent filter, security filter
A MessageRouter has multiple possible routes and is responsible for choosing which route should be used to continue message processing of a particular message. The MessageRouter interface allows multiple routes to be added (or removed).
There is a generic MessageProcessorBuilder interface for building MessageProcessors in the Mule 3 API, this is used internally only for now, but in the future in order to ensure MessageProcessors are created at the correct time users will almost certainly need to implement this interface when configuring some Message Processors.
The chaining of Message Processors happens behind the scenes when you configure a <service>, <flow>, endpoint or any other element that allows an ordered list of message processors to be supplied. Rather than force all Message Processors to implement InterceptingMessageProcessor to enable chaining we allow MessageProcessor implements that don’t care about the message flow to simply implement MessageProcessor and then when the chain is created these are adapted so as to use them in a chain.