Revisit JmsMessagingTemplate

This commit revisits JmsMessagingTemplate and adds support for
receiving operations as well. JmsMessageSendingOperations has been
renamed to JmsMessageOperations.

The messaging abstraction did not split receiving and request-reply
operations. AbstractMessageReceivingTemplate has been created to hold
only the receiving operations.

Issue: SPR-11772
This commit is contained in:
Stephane Nicoll
2014-05-26 09:32:54 +02:00
parent 31c07dbfa4
commit 9fabcad3dd
7 changed files with 317 additions and 43 deletions

View File

@@ -23,18 +23,20 @@ import javax.jms.Destination;
import org.springframework.messaging.Message;
import org.springframework.messaging.MessagingException;
import org.springframework.messaging.core.MessagePostProcessor;
import org.springframework.messaging.core.MessageReceivingOperations;
import org.springframework.messaging.core.MessageSendingOperations;
/**
* A specialization of {@link MessageSendingOperations} for JMS related
* operations that allows to specify a destination name rather than the
* A specialization of {@link MessageSendingOperations} and {@link MessageSendingOperations}
* for JMS related operations that allows to specify a destination name rather than the
* actual {@link javax.jms.Destination}
*
* @author Stephane Nicoll
* @since 4.1
* @see org.springframework.jms.core.JmsTemplate
*/
public interface JmsMessageSendingOperations extends MessageSendingOperations<Destination> {
public interface JmsMessageOperations
extends MessageSendingOperations<Destination>, MessageReceivingOperations<Destination> {
/**
* Send a message to the given destination.
@@ -89,4 +91,22 @@ public interface JmsMessageSendingOperations extends MessageSendingOperations<De
void convertAndSend(String destinationName, Object payload, Map<String,
Object> headers, MessagePostProcessor postProcessor) throws MessagingException;
/**
* Receive a message from the given destination.
* @param destinationName the name of the target destination
* @return the received message, possibly {@code null} if the message could not
* be received, for example due to a timeout
*/
Message<?> receive(String destinationName) throws MessagingException;
/**
* Receive a message from the given destination and convert its payload to the
* specified target class.
* @param destinationName the name of the target destination
* @param targetClass the target class to convert the payload to
* @return the converted payload of the reply message, possibly {@code null} if
* the message could not be received, for example due to a timeout
*/
<T> T receiveAndConvert(String destinationName, Class<T> targetClass) throws MessagingException;
}

View File

@@ -25,25 +25,26 @@ import javax.jms.Session;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.jms.core.JmsTemplate;
import org.springframework.jms.core.MessageCreator;
import org.springframework.jms.support.converter.MessageConversionException;
import org.springframework.jms.support.converter.MessageConverter;
import org.springframework.jms.support.converter.MessagingMessageConverter;
import org.springframework.jms.support.converter.SimpleJmsHeaderMapper;
import org.springframework.jms.support.converter.SimpleMessageConverter;
import org.springframework.messaging.Message;
import org.springframework.messaging.MessagingException;
import org.springframework.messaging.core.AbstractMessageSendingTemplate;
import org.springframework.messaging.core.AbstractMessageReceivingTemplate;
import org.springframework.messaging.core.MessagePostProcessor;
import org.springframework.util.Assert;
/**
* An implementation of {@link JmsMessageSendingOperations}.
* An implementation of {@link JmsMessageOperations}.
*
* @author Stephane Nicoll
* @since 4.1
*/
public class JmsMessagingTemplate
extends AbstractMessageSendingTemplate<Destination>
implements JmsMessageSendingOperations, InitializingBean {
extends AbstractMessageReceivingTemplate<Destination>
implements JmsMessageOperations, InitializingBean {
private JmsTemplate jmsTemplate;
@@ -165,6 +166,45 @@ public class JmsMessagingTemplate
send(destinationName, message);
}
@Override
public Message<?> receive() {
Destination defaultDestination = getDefaultDestination();
if (defaultDestination != null) {
return receive(defaultDestination);
}
else {
return receive(getRequiredDefaultDestinationName());
}
}
@Override
public <T> T receiveAndConvert(Class<T> targetClass) {
Destination defaultDestination = getDefaultDestination();
if (defaultDestination != null) {
return receiveAndConvert(defaultDestination, targetClass);
}
else {
return receiveAndConvert(getRequiredDefaultDestinationName(), targetClass);
}
}
@Override
public Message<?> receive(String destinationName) throws MessagingException {
return doReceive(destinationName);
}
@Override
@SuppressWarnings("unchecked")
public <T> T receiveAndConvert(String destinationName, Class<T> targetClass) throws MessagingException {
Message<?> message = doReceive(destinationName);
if (message != null) {
return (T) getMessageConverter().fromMessage(message, targetClass);
}
else {
return null;
}
}
@Override
protected void doSend(Destination destination, Message<?> message) {
jmsTemplate.send(destination, new MessagingMessageCreator(message, this.jmsMessageConverter));
@@ -174,6 +214,17 @@ public class JmsMessagingTemplate
jmsTemplate.send(destinationName, new MessagingMessageCreator(message, this.jmsMessageConverter));
}
@Override
protected Message<?> doReceive(Destination destination) {
javax.jms.Message jmsMessage = jmsTemplate.receive(destination);
return doConvert(jmsMessage);
}
protected Message<?> doReceive(String destinationName) {
javax.jms.Message jmsMessage = jmsTemplate.receive(destinationName);
return doConvert(jmsMessage);
}
protected String getRequiredDefaultDestinationName() {
String name = getDefaultDestinationName();
if (name == null) {
@@ -185,6 +236,18 @@ public class JmsMessagingTemplate
return name;
}
protected Message<?> doConvert(javax.jms.Message message) {
if (message == null) {
return null;
}
try {
return (Message<?>) jmsMessageConverter.fromMessage(message);
}
catch (JMSException e) {
throw new MessageConversionException("Could not convert '" + message + "'", e);
}
}
private static class MessagingMessageCreator implements MessageCreator {

View File

@@ -98,6 +98,9 @@ public class MessagingMessageConverter implements MessageConverter, Initializing
@SuppressWarnings("unchecked")
@Override
public Object fromMessage(javax.jms.Message message) throws JMSException, MessageConversionException {
if (message == null) {
return null;
}
Map<String, Object> mappedHeaders = this.headerMapper.toHeaders(message);
Object convertedObject = extractPayload(message);
MessageBuilder<Object> builder = (convertedObject instanceof org.springframework.messaging.Message) ?