org.springframework.amqp.rabbit.listener.adapter
Class MessageListenerAdapter

java.lang.Object
  extended by org.springframework.amqp.rabbit.listener.adapter.MessageListenerAdapter
All Implemented Interfaces:
org.springframework.amqp.core.MessageListener, ChannelAwareMessageListener

public class MessageListenerAdapter
extends java.lang.Object
implements org.springframework.amqp.core.MessageListener, ChannelAwareMessageListener

Message listener adapter that delegates the handling of messages to target listener methods via reflection, with flexible message type conversion. Allows listener methods to operate on message content types, completely independent from the Rabbit API.

By default, the content of incoming Rabbit messages gets extracted before being passed into the target listener method, to let the target method operate on message content types such as String or byte array instead of the raw Message. Message type conversion is delegated to a Spring AMQ MessageConverter. By default, a SimpleMessageConverter will be used. (If you do not want such automatic message conversion taking place, then be sure to set the MessageConverter to null.)

If a target listener method returns a non-null object (typically of a message content type such as String or byte array), it will get wrapped in a Rabbit Message and sent to the exchange of the incoming message with the routingKey that comes from the Rabbit ReplyTo property or via specified routingKey).

Note: The sending of response messages is only available when using the ChannelAwareMessageListener entry point (typically through a Spring message listener container). Usage as MessageListener does not support the generation of response messages.

Find below some examples of method signatures compliant with this adapter class. This first example handles all Message types and gets passed the contents of each Message type as an argument. No Message will be sent back as all of these methods return void.

 public interface MessageContentsDelegate {
        void handleMessage(String text);

        void handleMessage(Map map);

        void handleMessage(byte[] bytes);

        void handleMessage(Serializable obj);
 }
 
This next example handle a Message type and gets passed the actual (raw) Message as an argument. Again, no Message will be sent back as all of these methods return void.
 public interface RawMessageDelegate {
        void handleMessage(Message message);
 }
 
This next example illustrates a Message delegate that just consumes the String contents of Messages. Notice also how the name of the Message handling method is different from the original (this will have to be configured in the attandant bean definition). Again, no Message will be sent back as the method returns void.
 public interface TextMessageContentDelegate {
        void onMessage(String text);
 }
 
This final example illustrates a Message delegate that just consumes the String contents of Messages. Notice how the return type of this method is String: This will result in the configured MessageListenerAdapter sending a Message in response.
 public interface ResponsiveTextMessageContentDelegate {
        String handleMessage(String text);
 }
 
For further examples and discussion please do refer to the Spring reference documentation which describes this class (and its attendant XML configuration) in detail.

See Also:
setDelegate(java.lang.Object), setDefaultListenerMethod(java.lang.String), setResponseRoutingKey(String), setMessageConverter(org.springframework.amqp.support.converter.MessageConverter), SimpleMessageConverter, ChannelAwareMessageListener, AbstractMessageListenerContainer.setMessageListener(java.lang.Object)

Field Summary
protected  org.apache.commons.logging.Log logger
          Logger available to subclasses
static java.lang.String ORIGINAL_DEFAULT_LISTENER_METHOD
          Out-of-the-box value for the default listener method: "handleMessage".
 
Constructor Summary
MessageListenerAdapter()
          Create a new MessageListenerAdapter with default settings.
MessageListenerAdapter(java.lang.Object delegate)
          Create a new MessageListenerAdapter for the given delegate.
MessageListenerAdapter(java.lang.Object delegate, org.springframework.amqp.support.converter.MessageConverter messageConverter)
          Create a new MessageListenerAdapter for the given delegate.
MessageListenerAdapter(java.lang.Object delegate, java.lang.String defaultListenerMethod)
          Create a new MessageListenerAdapter for the given delegate while also declaring its POJO method.
 
Method Summary
protected  java.lang.Object[] buildListenerArguments(java.lang.Object extractedMessage)
          Build an array of arguments to be passed into the target listener method.
protected  org.springframework.amqp.core.Message buildMessage(com.rabbitmq.client.Channel session, java.lang.Object result)
          Build a Rabbit message to be sent as response based on the given result object.
protected  java.lang.Object extractMessage(org.springframework.amqp.core.Message message)
          Extract the message body from the given Rabbit message.
protected  java.lang.String getDefaultListenerMethod()
          Return the name of the default listener method to delegate to.
protected  java.lang.Object getDelegate()
          Return the target object to delegate message listening to.
protected  java.lang.String getListenerMethodName(org.springframework.amqp.core.Message originalMessage, java.lang.Object extractedMessage)
          Determine the name of the listener method that is supposed to handle the given message.
protected  org.springframework.amqp.support.converter.MessageConverter getMessageConverter()
          Return the converter that will convert incoming Rabbit messages to listener method arguments, and objects returned from listener methods back to Rabbit messages.
protected  java.lang.String getReceivedExchange(org.springframework.amqp.core.Message request)
           
protected  org.springframework.amqp.core.Address getReplyToAddress(org.springframework.amqp.core.Message request)
          Determine a reply-to Address for the given message.
protected  void handleListenerException(java.lang.Throwable ex)
          Handle the given exception that arose during listener execution.
protected  void handleResult(java.lang.Object result, org.springframework.amqp.core.Message request, com.rabbitmq.client.Channel channel)
          Handle the given result object returned from the listener method, sending a response message back.
protected  void initDefaultStrategies()
          Initialize the default implementations for the adapter's strategies.
protected  java.lang.Object invokeListenerMethod(java.lang.String methodName, java.lang.Object[] arguments)
          Invoke the specified listener method.
 void onMessage(org.springframework.amqp.core.Message message)
          Rabbit MessageListener entry point.
 void onMessage(org.springframework.amqp.core.Message message, com.rabbitmq.client.Channel channel)
          Spring ChannelAwareMessageListener entry point.
protected  void postProcessChannel(com.rabbitmq.client.Channel channel, org.springframework.amqp.core.Message response)
          Post-process the given message producer before using it to send the response.
protected  void postProcessResponse(org.springframework.amqp.core.Message request, org.springframework.amqp.core.Message response)
          Post-process the given response message before it will be sent.
protected  void sendResponse(com.rabbitmq.client.Channel channel, org.springframework.amqp.core.Address replyTo, org.springframework.amqp.core.Message message)
          Send the given response message to the given destination.
 void setDefaultListenerMethod(java.lang.String defaultListenerMethod)
          Specify the name of the default listener method to delegate to, for the case where no specific listener method has been determined.
 void setDelegate(java.lang.Object delegate)
          Set a target object to delegate message listening to.
 void setEncoding(java.lang.String encoding)
          The encoding to use when inter-converting between byte arrays and Strings in message properties.
 void setImmediatePublish(boolean immediatePublish)
           
 void setMandatoryPublish(boolean mandatoryPublish)
           
 void setMessageConverter(org.springframework.amqp.support.converter.MessageConverter messageConverter)
          Set the converter that will convert incoming Rabbit messages to listener method arguments, and objects returned from listener methods back to Rabbit messages.
 void setResponseExchange(java.lang.String responseExchange)
          Set the exchange to use when sending response messages.
 void setResponseRoutingKey(java.lang.String responseRoutingKey)
          Set the routing key to use when sending response messages.
 
Methods inherited from class java.lang.Object
clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
 

Field Detail

ORIGINAL_DEFAULT_LISTENER_METHOD

public static final java.lang.String ORIGINAL_DEFAULT_LISTENER_METHOD
Out-of-the-box value for the default listener method: "handleMessage".

See Also:
Constant Field Values

logger

protected final org.apache.commons.logging.Log logger
Logger available to subclasses

Constructor Detail

MessageListenerAdapter

public MessageListenerAdapter()
Create a new MessageListenerAdapter with default settings.


MessageListenerAdapter

public MessageListenerAdapter(java.lang.Object delegate)
Create a new MessageListenerAdapter for the given delegate.

Parameters:
delegate - the delegate object

MessageListenerAdapter

public MessageListenerAdapter(java.lang.Object delegate,
                              org.springframework.amqp.support.converter.MessageConverter messageConverter)
Create a new MessageListenerAdapter for the given delegate.

Parameters:
delegate - the delegate object
messageConverter - the message converter to use

MessageListenerAdapter

public MessageListenerAdapter(java.lang.Object delegate,
                              java.lang.String defaultListenerMethod)
Create a new MessageListenerAdapter for the given delegate while also declaring its POJO method.

Parameters:
delegate - the delegate object
defaultListenerMethod - name of the POJO method to call upon message receipt
Method Detail

setDelegate

public void setDelegate(java.lang.Object delegate)
Set a target object to delegate message listening to. Specified listener methods have to be present on this target object.

If no explicit delegate object has been specified, listener methods are expected to present on this adapter instance, that is, on a custom subclass of this adapter, defining listener methods.


getDelegate

protected java.lang.Object getDelegate()
Return the target object to delegate message listening to.


setEncoding

public void setEncoding(java.lang.String encoding)
The encoding to use when inter-converting between byte arrays and Strings in message properties.

Parameters:
encoding - the encoding to set

setDefaultListenerMethod

public void setDefaultListenerMethod(java.lang.String defaultListenerMethod)
Specify the name of the default listener method to delegate to, for the case where no specific listener method has been determined. Out-of-the-box value is "handleMessage".

See Also:
getListenerMethodName(org.springframework.amqp.core.Message, java.lang.Object)

getDefaultListenerMethod

protected java.lang.String getDefaultListenerMethod()
Return the name of the default listener method to delegate to.


setResponseRoutingKey

public void setResponseRoutingKey(java.lang.String responseRoutingKey)
Set the routing key to use when sending response messages. This will be applied in case of a request message that does not carry a "ReplyTo" property

Response destinations are only relevant for listener methods that return result objects, which will be wrapped in a response message and sent to a response destination.


setResponseExchange

public void setResponseExchange(java.lang.String responseExchange)
Set the exchange to use when sending response messages. This is only used if the exchange from the received message is null.

Response destinations are only relevant for listener methods that return result objects, which will be wrapped in a response message and sent to a response destination.

Parameters:
responseExchange -

setMessageConverter

public void setMessageConverter(org.springframework.amqp.support.converter.MessageConverter messageConverter)
Set the converter that will convert incoming Rabbit messages to listener method arguments, and objects returned from listener methods back to Rabbit messages.

The default converter is a SimpleMessageConverter, which is able to handle "text" content-types.


getMessageConverter

protected org.springframework.amqp.support.converter.MessageConverter getMessageConverter()
Return the converter that will convert incoming Rabbit messages to listener method arguments, and objects returned from listener methods back to Rabbit messages.


setMandatoryPublish

public void setMandatoryPublish(boolean mandatoryPublish)

setImmediatePublish

public void setImmediatePublish(boolean immediatePublish)

onMessage

public void onMessage(org.springframework.amqp.core.Message message)
Rabbit MessageListener entry point.

Delegates the message to the target listener method, with appropriate conversion of the message argument. In case of an exception, the handleListenerException(Throwable) method will be invoked.

Note: Does not support sending response messages based on result objects returned from listener methods. Use the ChannelAwareMessageListener entry point (typically through a Spring message listener container) for handling result objects as well.

Specified by:
onMessage in interface org.springframework.amqp.core.MessageListener
Parameters:
message - the incoming Rabbit message
See Also:
handleListenerException(java.lang.Throwable), onMessage(Message, Channel)

onMessage

public void onMessage(org.springframework.amqp.core.Message message,
                      com.rabbitmq.client.Channel channel)
               throws java.lang.Exception
Spring ChannelAwareMessageListener entry point.

Delegates the message to the target listener method, with appropriate conversion of the message argument. If the target method returns a non-null object, wrap in a Rabbit message and send it back.

Specified by:
onMessage in interface ChannelAwareMessageListener
Parameters:
message - the incoming Rabbit message
channel - the Rabbit channel to operate on
Throws:
java.lang.Exception - if thrown by Rabbit API methods

initDefaultStrategies

protected void initDefaultStrategies()
Initialize the default implementations for the adapter's strategies.

See Also:
setMessageConverter(org.springframework.amqp.support.converter.MessageConverter), SimpleMessageConverter

handleListenerException

protected void handleListenerException(java.lang.Throwable ex)
Handle the given exception that arose during listener execution. The default implementation logs the exception at error level.

This method only applies when using a Rabbit MessageListener. With ChannelAwareMessageListener, exceptions get handled by the caller instead.

Parameters:
ex - the exception to handle
See Also:
onMessage(Message)

extractMessage

protected java.lang.Object extractMessage(org.springframework.amqp.core.Message message)
                                   throws java.lang.Exception
Extract the message body from the given Rabbit message.

Parameters:
message - the Rabbit Message
Returns:
the content of the message, to be passed into the listener method as argument
Throws:
java.lang.Exception - if thrown by Rabbit API methods

getListenerMethodName

protected java.lang.String getListenerMethodName(org.springframework.amqp.core.Message originalMessage,
                                                 java.lang.Object extractedMessage)
                                          throws java.lang.Exception
Determine the name of the listener method that is supposed to handle the given message.

The default implementation simply returns the configured default listener method, if any.

Parameters:
originalMessage - the Rabbit request message
extractedMessage - the converted Rabbit request message, to be passed into the listener method as argument
Returns:
the name of the listener method (never null)
Throws:
java.lang.Exception - if thrown by Rabbit API methods
See Also:
setDefaultListenerMethod(java.lang.String)

buildListenerArguments

protected java.lang.Object[] buildListenerArguments(java.lang.Object extractedMessage)
Build an array of arguments to be passed into the target listener method. Allows for multiple method arguments to be built from a single message object.

The default implementation builds an array with the given message object as sole element. This means that the extracted message will always be passed into a single method argument, even if it is an array, with the target method having a corresponding single argument of the array's type declared.

This can be overridden to treat special message content such as arrays differently, for example passing in each element of the message array as distinct method argument.

Parameters:
extractedMessage - the content of the message
Returns:
the array of arguments to be passed into the listener method (each element of the array corresponding to a distinct method argument)

invokeListenerMethod

protected java.lang.Object invokeListenerMethod(java.lang.String methodName,
                                                java.lang.Object[] arguments)
                                         throws java.lang.Exception
Invoke the specified listener method.

Parameters:
methodName - the name of the listener method
arguments - the message arguments to be passed in
Returns:
the result returned from the listener method
Throws:
java.lang.Exception - if thrown by Rabbit API methods
See Also:
getListenerMethodName(org.springframework.amqp.core.Message, java.lang.Object), buildListenerArguments(java.lang.Object)

handleResult

protected void handleResult(java.lang.Object result,
                            org.springframework.amqp.core.Message request,
                            com.rabbitmq.client.Channel channel)
                     throws java.lang.Exception
Handle the given result object returned from the listener method, sending a response message back.

Parameters:
result - the result object to handle (never null)
request - the original request message
channel - the Rabbit channel to operate on (may be null)
Throws:
java.lang.Exception - if thrown by Rabbit API methods
See Also:
buildMessage(com.rabbitmq.client.Channel, java.lang.Object), postProcessResponse(org.springframework.amqp.core.Message, org.springframework.amqp.core.Message), getReplyToAddress(Message), sendResponse(com.rabbitmq.client.Channel, org.springframework.amqp.core.Address, org.springframework.amqp.core.Message)

getReceivedExchange

protected java.lang.String getReceivedExchange(org.springframework.amqp.core.Message request)

buildMessage

protected org.springframework.amqp.core.Message buildMessage(com.rabbitmq.client.Channel session,
                                                             java.lang.Object result)
                                                      throws java.lang.Exception
Build a Rabbit message to be sent as response based on the given result object.

Parameters:
session - the Rabbit Channel to operate on
result - the content of the message, as returned from the listener method
Returns:
the Rabbit Message (never null)
Throws:
java.lang.Exception - if thrown by Rabbit API methods
See Also:
setMessageConverter(org.springframework.amqp.support.converter.MessageConverter)

postProcessResponse

protected void postProcessResponse(org.springframework.amqp.core.Message request,
                                   org.springframework.amqp.core.Message response)
                            throws java.lang.Exception
Post-process the given response message before it will be sent.

The default implementation sets the response's correlation id to the request message's correlation id, if any; otherwise to the request message id.

Parameters:
request - the original incoming Rabbit message
response - the outgoing Rabbit message about to be sent
Throws:
java.lang.Exception - if thrown by Rabbit API methods

getReplyToAddress

protected org.springframework.amqp.core.Address getReplyToAddress(org.springframework.amqp.core.Message request)
                                                           throws java.lang.Exception
Determine a reply-to Address for the given message.

The default implementation first checks the Rabbit Reply-To Address of the supplied request; if that is not null it is returned; if it is null, then the configured default response Exchange and routing key are used to construct a reply-to Address. If the responseExchange property is also null, then an AmqpException is thrown.

Parameters:
request - the original incoming Rabbit message
Returns:
the reply-to Address (never null)
Throws:
java.lang.Exception - if thrown by Rabbit API methods
org.springframework.amqp.AmqpException - if no Address can be determined
See Also:
setResponseExchange(String), setResponseRoutingKey(String), Message.getMessageProperties(), MessageProperties.getReplyTo()

sendResponse

protected void sendResponse(com.rabbitmq.client.Channel channel,
                            org.springframework.amqp.core.Address replyTo,
                            org.springframework.amqp.core.Message message)
                     throws java.lang.Exception
Send the given response message to the given destination.

Parameters:
channel - the Rabbit channel to operate on
replyTo - the Rabbit ReplyTo string to use when sending. Currently interpreted to be the routing key.
message - the Rabbit message to send
Throws:
java.lang.Exception - if thrown by Rabbit API methods
See Also:
postProcessResponse(Message, Message)

postProcessChannel

protected void postProcessChannel(com.rabbitmq.client.Channel channel,
                                  org.springframework.amqp.core.Message response)
                           throws java.lang.Exception
Post-process the given message producer before using it to send the response.

The default implementation is empty.

Parameters:
response - the outgoing Rabbit message about to be sent
Throws:
java.lang.Exception - if thrown by Rabbit API methods