High-level templates for simplified message sending and receiving with destination resolution, message conversion, and request-reply patterns. Templates abstract the complexity of channel operations and provide fluent APIs for common messaging tasks.
Primary template for message operations with MessageChannel destinations, supporting send, receive, and request-reply patterns.
/**
* A messaging template that resolves destinations names to MessageChannels
* to send and receive messages from.
*/
public class GenericMessagingTemplate
extends AbstractDestinationResolvingMessagingTemplate<MessageChannel>
implements BeanFactoryAware {
/**
* Header name for send timeout (in milliseconds).
*/
public static final String DEFAULT_SEND_TIMEOUT_HEADER = "sendTimeout";
/**
* Header name for receive timeout (in milliseconds).
*/
public static final String DEFAULT_RECEIVE_TIMEOUT_HEADER = "receiveTimeout";
/**
* Create a GenericMessagingTemplate with the given default destination.
* @param defaultDestination the default MessageChannel to use for sending/receiving
*/
public GenericMessagingTemplate(MessageChannel defaultDestination);
/**
* Configure the default destination to send/receive messages to/from.
*/
public void setDefaultDestination(@Nullable MessageChannel defaultDestination);
/**
* Return the configured default destination.
*/
@Nullable
public MessageChannel getDefaultDestination();
/**
* Specify the timeout value to use for send operations (in milliseconds).
* Default is -1 (indefinite).
*/
public void setSendTimeout(long sendTimeout);
/**
* Return the configured send timeout.
*/
public long getSendTimeout();
/**
* Specify the timeout value to use for receive operations (in milliseconds).
* Default is -1 (indefinite).
*/
public void setReceiveTimeout(long receiveTimeout);
/**
* Return the configured receive timeout.
*/
public long getReceiveTimeout();
/**
* Specify the name of the header for send timeout.
* Default is "sendTimeout".
*/
public void setSendTimeoutHeader(String sendTimeoutHeader);
/**
* Return the configured send timeout header name.
*/
public String getSendTimeoutHeader();
/**
* Specify the name of the header for receive timeout.
* Default is "receiveTimeout".
*/
public void setReceiveTimeoutHeader(String receiveTimeoutHeader);
/**
* Return the configured receive timeout header name.
*/
public String getReceiveTimeoutHeader();
/**
* Whether the template should throw a MessageDeliveryException if a
* reply is received after the receive timeout. Default is false.
*/
public void setThrowExceptionOnLateReply(boolean throwExceptionOnLateReply);
/**
* Set the MessageConverter to use for converting between messages and objects.
*/
public void setMessageConverter(MessageConverter messageConverter);
/**
* Return the configured MessageConverter.
*/
public MessageConverter getMessageConverter();
/**
* Set the DestinationResolver to use for resolving destination names.
*/
public void setDestinationResolver(@Nullable DestinationResolver<MessageChannel> destinationResolver);
/**
* Return the configured DestinationResolver.
*/
@Nullable
public DestinationResolver<MessageChannel> getDestinationResolver();
@Override
public void setBeanFactory(BeanFactory beanFactory);
// Inherited sending operations
@Override
public void send(Message<?> message);
@Override
public void send(MessageChannel destination, Message<?> message);
@Override
public void send(String destinationName, Message<?> message);
@Override
public <T> void convertAndSend(T payload);
@Override
public <T> void convertAndSend(MessageChannel destination, T payload);
@Override
public <T> void convertAndSend(String destinationName, T payload);
@Override
public <T> void convertAndSend(T payload, Map<String, Object> headers);
@Override
public <T> void convertAndSend(MessageChannel destination, T payload, Map<String, Object> headers);
@Override
public <T> void convertAndSend(String destinationName, T payload, Map<String, Object> headers);
@Override
public <T> void convertAndSend(T payload, MessagePostProcessor postProcessor);
@Override
public <T> void convertAndSend(MessageChannel destination, T payload, MessagePostProcessor postProcessor);
@Override
public <T> void convertAndSend(String destinationName, T payload, MessagePostProcessor postProcessor);
@Override
public <T> void convertAndSend(T payload, Map<String, Object> headers, MessagePostProcessor postProcessor);
@Override
public <T> void convertAndSend(MessageChannel destination, T payload,
Map<String, Object> headers, MessagePostProcessor postProcessor);
@Override
public <T> void convertAndSend(String destinationName, T payload,
Map<String, Object> headers, MessagePostProcessor postProcessor);
// Receiving operations
@Override
@Nullable
public Message<?> receive();
@Override
@Nullable
public Message<?> receive(MessageChannel destination);
@Override
@Nullable
public Message<?> receive(String destinationName);
@Override
@Nullable
public <T> T receiveAndConvert(Class<T> targetClass);
@Override
@Nullable
public <T> T receiveAndConvert(MessageChannel destination, Class<T> targetClass);
@Override
@Nullable
public <T> T receiveAndConvert(String destinationName, Class<T> targetClass);
// Request-reply operations
@Override
@Nullable
public Message<?> sendAndReceive(Message<?> requestMessage);
@Override
@Nullable
public Message<?> sendAndReceive(MessageChannel destination, Message<?> requestMessage);
@Override
@Nullable
public Message<?> sendAndReceive(String destinationName, Message<?> requestMessage);
@Override
@Nullable
public <T> T convertSendAndReceive(Object request, Class<T> targetClass);
@Override
@Nullable
public <T> T convertSendAndReceive(MessageChannel destination, Object request, Class<T> targetClass);
@Override
@Nullable
public <T> T convertSendAndReceive(String destinationName, Object request, Class<T> targetClass);
@Override
@Nullable
public <T> T convertSendAndReceive(Object request, Map<String, Object> headers, Class<T> targetClass);
@Override
@Nullable
public <T> T convertSendAndReceive(MessageChannel destination, Object request,
Map<String, Object> headers, Class<T> targetClass);
@Override
@Nullable
public <T> T convertSendAndReceive(String destinationName, Object request,
Map<String, Object> headers, Class<T> targetClass);
@Override
@Nullable
public <T> T convertSendAndReceive(Object request, Class<T> targetClass, MessagePostProcessor postProcessor);
@Override
@Nullable
public <T> T convertSendAndReceive(MessageChannel destination, Object request,
Class<T> targetClass, MessagePostProcessor postProcessor);
@Override
@Nullable
public <T> T convertSendAndReceive(String destinationName, Object request,
Class<T> targetClass, MessagePostProcessor postProcessor);
@Override
@Nullable
public <T> T convertSendAndReceive(Object request, Map<String, Object> headers,
Class<T> targetClass, MessagePostProcessor postProcessor);
@Override
@Nullable
public <T> T convertSendAndReceive(MessageChannel destination, Object request,
Map<String, Object> headers, Class<T> targetClass,
MessagePostProcessor postProcessor);
@Override
@Nullable
public <T> T convertSendAndReceive(String destinationName, Object request,
Map<String, Object> headers, Class<T> targetClass,
MessagePostProcessor postProcessor);
}Usage Examples:
import org.springframework.messaging.core.GenericMessagingTemplate;
import org.springframework.messaging.MessageChannel;
import org.springframework.messaging.Message;
import org.springframework.messaging.support.ExecutorSubscribableChannel;
import org.springframework.messaging.support.MessageBuilder;
import org.springframework.messaging.converter.MappingJackson2MessageConverter;
import java.util.HashMap;
import java.util.Map;
// Create channel and template
MessageChannel channel = new ExecutorSubscribableChannel();
GenericMessagingTemplate template = new GenericMessagingTemplate(channel);
// Configure timeouts
template.setSendTimeout(5000); // 5 seconds
template.setReceiveTimeout(3000); // 3 seconds
// Configure converter
template.setMessageConverter(new MappingJackson2MessageConverter());
// Simple send
Message<String> message = MessageBuilder
.withPayload("Hello World")
.build();
template.send(message);
// Convert and send
User user = new User("john", "john@example.com");
template.convertAndSend(user);
// Send with headers
Map<String, Object> headers = new HashMap<>();
headers.put("priority", "high");
headers.put("timestamp", System.currentTimeMillis());
template.convertAndSend(user, headers);
// Send with post-processor
template.convertAndSend(user, message -> {
MessageBuilder.fromMessage(message)
.setHeader("processed", true)
.build();
});
// Request-reply pattern
String response = template.convertSendAndReceive("Hello", String.class);
System.out.println("Response: " + response);
// Named destination support (requires DestinationResolver)
template.send("myQueue", message);
template.convertAndSend("/topic/updates", user);
class User {
private String name;
private String email;
public User(String name, String email) {
this.name = name;
this.email = email;
}
// Getters and setters
public String getName() { return name; }
public void setName(String name) { this.name = name; }
public String getEmail() { return email; }
public void setEmail(String email) { this.email = email; }
}Specialized template for Simple Messaging Protocol with user-specific destination support.
/**
* An implementation of MessageSendingOperations for use with the
* Simple Messaging Protocol. Adds support for user-specific destinations.
*/
public class SimpMessagingTemplate
extends AbstractDestinationResolvingMessagingTemplate<String>
implements SimpMessageSendingOperations {
/**
* Create a SimpMessagingTemplate with the given MessageChannel.
* @param messageChannel the channel to send messages to
*/
public SimpMessagingTemplate(MessageChannel messageChannel);
/**
* Return the configured MessageChannel.
*/
public MessageChannel getMessageChannel();
/**
* Set the prefix for user destinations. Default is "/user/".
* @param prefix the prefix to use
*/
public void setUserDestinationPrefix(String prefix);
/**
* Return the configured user destination prefix.
*/
public String getUserDestinationPrefix();
/**
* Specify the timeout value to use for send operations (in milliseconds).
* Default is -1 (indefinite).
*/
public void setSendTimeout(long sendTimeout);
/**
* Return the configured send timeout.
*/
public long getSendTimeout();
/**
* Set the MessageHeaderInitializer to apply to the headers of all
* messages created through this template.
*/
public void setHeaderInitializer(@Nullable MessageHeaderInitializer headerInitializer);
/**
* Return the configured MessageHeaderInitializer.
*/
@Nullable
public MessageHeaderInitializer getHeaderInitializer();
/**
* Set the MessageConverter to use for converting between messages and objects.
*/
public void setMessageConverter(MessageConverter messageConverter);
/**
* Return the configured MessageConverter.
*/
public MessageConverter getMessageConverter();
@Override
public void send(Message<?> message);
@Override
public void send(String destination, Message<?> message);
@Override
public <T> void convertAndSend(String destination, T payload);
@Override
public <T> void convertAndSend(String destination, T payload, Map<String, Object> headers);
@Override
public <T> void convertAndSend(String destination, T payload, MessagePostProcessor postProcessor);
@Override
public <T> void convertAndSend(String destination, T payload,
Map<String, Object> headers, MessagePostProcessor postProcessor);
/**
* Send a message to a user-specific destination.
* @param user the user name (destination will be prefixed with user destination prefix)
* @param destination the destination (without user prefix)
* @param payload the payload to send
*/
@Override
public void convertAndSendToUser(String user, String destination, Object payload);
/**
* Send a message to a user-specific destination with headers.
* @param user the user name
* @param destination the destination
* @param payload the payload to send
* @param headers headers to include
*/
@Override
public void convertAndSendToUser(String user, String destination, Object payload,
Map<String, Object> headers);
/**
* Send a message to a user-specific destination with a post-processor.
* @param user the user name
* @param destination the destination
* @param payload the payload to send
* @param postProcessor post-processor to apply to the message
*/
@Override
public void convertAndSendToUser(String user, String destination, Object payload,
MessagePostProcessor postProcessor);
/**
* Send a message to a user-specific destination with headers and a post-processor.
* @param user the user name
* @param destination the destination
* @param payload the payload to send
* @param headers headers to include
* @param postProcessor post-processor to apply to the message
*/
@Override
public void convertAndSendToUser(String user, String destination, Object payload,
Map<String, Object> headers, MessagePostProcessor postProcessor);
}Usage Examples:
import org.springframework.messaging.simp.SimpMessagingTemplate;
import org.springframework.messaging.MessageChannel;
import org.springframework.messaging.support.ExecutorSubscribableChannel;
import org.springframework.messaging.converter.MappingJackson2MessageConverter;
import java.util.HashMap;
import java.util.Map;
// Create channel and template
MessageChannel channel = new ExecutorSubscribableChannel();
SimpMessagingTemplate template = new SimpMessagingTemplate(channel);
// Configure converter
template.setMessageConverter(new MappingJackson2MessageConverter());
// Configure user destination prefix (default is "/user/")
template.setUserDestinationPrefix("/user/");
// Configure timeout
template.setSendTimeout(5000);
// Send to topic (broadcast)
template.convertAndSend("/topic/news", "Breaking news!");
// Send to specific queue
Map<String, Object> headers = new HashMap<>();
headers.put("priority", "high");
template.convertAndSend("/queue/tasks", new Task("process-data"), headers);
// Send to specific user
String username = "john";
Notification notification = new Notification("New message for you");
template.convertAndSendToUser(username, "/queue/notifications", notification);
// Send to user with headers
Map<String, Object> userHeaders = new HashMap<>();
userHeaders.put("timestamp", System.currentTimeMillis());
template.convertAndSendToUser(username, "/queue/updates",
new Update("Your order has shipped"), userHeaders);
// Send to user with post-processor
template.convertAndSendToUser(username, "/queue/alerts",
new Alert("Security notice"),
message -> MessageBuilder.fromMessage(message)
.setHeader("urgent", true)
.build()
);
// Broadcast to all users subscribed to a topic
List<String> users = Arrays.asList("john", "jane", "bob");
for (String user : users) {
template.convertAndSendToUser(user, "/queue/broadcast",
"System maintenance in 10 minutes");
}
class Task {
private String action;
public Task(String action) { this.action = action; }
public String getAction() { return action; }
public void setAction(String action) { this.action = action; }
}
class Notification {
private String message;
public Notification(String message) { this.message = message; }
public String getMessage() { return message; }
public void setMessage(String message) { this.message = message; }
}
class Update {
private String info;
public Update(String info) { this.info = info; }
public String getInfo() { return info; }
public void setInfo(String info) { this.info = info; }
}
class Alert {
private String warning;
public Alert(String warning) { this.warning = warning; }
public String getWarning() { return warning; }
public void setWarning(String warning) { this.warning = warning; }
}Base operations interface for sending messages to destinations.
/**
* Operations for sending messages to a destination.
*
* @param <D> the destination type
*/
public interface MessageSendingOperations<D> {
/**
* Send a message to the default destination.
* @param message the message to send
*/
void send(Message<?> message);
/**
* Send a message to the given destination.
* @param destination the target destination
* @param message the message to send
*/
void send(D destination, Message<?> message);
/**
* Convert the given Object to serialized form, wrap it as a message and
* send it to the default destination.
* @param payload the Object to use as payload
*/
<T> void convertAndSend(T payload);
/**
* Convert the given Object to serialized form, wrap it as a message and
* send it to the given destination.
* @param destination the target destination
* @param payload the Object to use as payload
*/
<T> void convertAndSend(D destination, T payload);
/**
* Convert the given Object to serialized form, wrap it as a message with
* the given headers and send it to the given destination.
* @param destination the target destination
* @param payload the Object to use as payload
* @param headers headers for the message
*/
<T> void convertAndSend(D destination, T payload, @Nullable Map<String, Object> headers);
/**
* Convert the given Object to serialized form, wrap it as a message,
* apply the post-processor and send it to the default destination.
* @param payload the Object to use as payload
* @param postProcessor a post-processor to apply to the message
*/
<T> void convertAndSend(T payload, @Nullable MessagePostProcessor postProcessor);
/**
* Convert the given Object to serialized form, wrap it as a message,
* apply the post-processor and send it to the given destination.
* @param destination the target destination
* @param payload the Object to use as payload
* @param postProcessor a post-processor to apply to the message
*/
<T> void convertAndSend(D destination, T payload, @Nullable MessagePostProcessor postProcessor);
/**
* Convert the given Object to serialized form, wrap it as a message with
* the given headers, apply the post-processor and send to the given destination.
* @param destination the target destination
* @param payload the Object to use as payload
* @param headers headers for the message
* @param postProcessor a post-processor to apply to the message
*/
<T> void convertAndSend(D destination, T payload, @Nullable Map<String, Object> headers,
@Nullable MessagePostProcessor postProcessor);
}Operations interface for receiving messages from destinations.
/**
* Operations for receiving messages from a destination.
*
* @param <D> the destination type
*/
public interface MessageReceivingOperations<D> {
/**
* Receive a message from the default destination.
* @return the received message, or null if no message available
*/
@Nullable
Message<?> receive();
/**
* Receive a message from the given destination.
* @param destination the target destination
* @return the received message, or null if no message available
*/
@Nullable
Message<?> receive(D destination);
/**
* Receive a message from the default destination and convert its payload
* to the specified target class.
* @param targetClass the target class to convert the payload to
* @return the converted payload, or null if no message available
*/
@Nullable
<T> T receiveAndConvert(Class<T> targetClass);
/**
* Receive a message from the given destination and convert its payload
* to the specified target class.
* @param destination the target destination
* @param targetClass the target class to convert the payload to
* @return the converted payload, or null if no message available
*/
@Nullable
<T> T receiveAndConvert(D destination, Class<T> targetClass);
}Operations interface for request-reply messaging patterns.
/**
* Operations for sending messages to and receiving the reply from a destination.
*
* @param <D> the destination type
*/
public interface MessageRequestReplyOperations<D> {
/**
* Send a request message and receive a reply from the default destination.
* @param requestMessage the message to send
* @return the reply message, or null if no reply
*/
@Nullable
Message<?> sendAndReceive(Message<?> requestMessage);
/**
* Send a request message and receive a reply from the given destination.
* @param destination the target destination
* @param requestMessage the message to send
* @return the reply message, or null if no reply
*/
@Nullable
Message<?> sendAndReceive(D destination, Message<?> requestMessage);
/**
* Convert the given request Object to serialized form, send as a message to
* the default destination, receive the reply and convert to the target class.
* @param request the Object to use as request payload
* @param targetClass the target class to convert the reply to
* @return the converted reply payload, or null if no reply
*/
@Nullable
<T> T convertSendAndReceive(Object request, Class<T> targetClass);
/**
* Convert the given request Object to serialized form, send as a message to
* the given destination, receive the reply and convert to the target class.
* @param destination the target destination
* @param request the Object to use as request payload
* @param targetClass the target class to convert the reply to
* @return the converted reply payload, or null if no reply
*/
@Nullable
<T> T convertSendAndReceive(D destination, Object request, Class<T> targetClass);
/**
* Convert the given request Object, send as a message with headers to
* the given destination, receive the reply and convert to the target class.
* @param destination the target destination
* @param request the Object to use as request payload
* @param headers headers for the message
* @param targetClass the target class to convert the reply to
* @return the converted reply payload, or null if no reply
*/
@Nullable
<T> T convertSendAndReceive(D destination, Object request, @Nullable Map<String, Object> headers,
Class<T> targetClass);
/**
* Convert the given request Object, send as a message to the given destination
* with a post-processor, receive the reply and convert to the target class.
* @param destination the target destination
* @param request the Object to use as request payload
* @param targetClass the target class to convert the reply to
* @param postProcessor a post-processor to apply to the request message
* @return the converted reply payload, or null if no reply
*/
@Nullable
<T> T convertSendAndReceive(D destination, Object request, Class<T> targetClass,
@Nullable MessagePostProcessor postProcessor);
/**
* Convert the given request Object, send as a message with headers and
* post-processor to the given destination, receive reply and convert to target class.
* @param destination the target destination
* @param request the Object to use as request payload
* @param headers headers for the message
* @param targetClass the target class to convert the reply to
* @param postProcessor a post-processor to apply to the request message
* @return the converted reply payload, or null if no reply
*/
@Nullable
<T> T convertSendAndReceive(D destination, Object request, @Nullable Map<String, Object> headers,
Class<T> targetClass, @Nullable MessagePostProcessor postProcessor);
}Extension of MessageSendingOperations with user-specific destination support.
/**
* A specialization of MessageSendingOperations with methods for use with
* the Simple Messaging Protocol (for example, STOMP over WebSocket).
*/
public interface SimpMessageSendingOperations extends MessageSendingOperations<String> {
/**
* Send a message to a user-specific destination.
* @param user the user name (destination will be prefixed)
* @param destination the destination path
* @param payload the payload to send
*/
void convertAndSendToUser(String user, String destination, Object payload);
/**
* Send a message to a user-specific destination with headers.
* @param user the user name
* @param destination the destination path
* @param payload the payload to send
* @param headers headers for the message
*/
void convertAndSendToUser(String user, String destination, Object payload,
@Nullable Map<String, Object> headers);
/**
* Send a message to a user-specific destination with a post-processor.
* @param user the user name
* @param destination the destination path
* @param payload the payload to send
* @param postProcessor post-processor to apply to the message
*/
void convertAndSendToUser(String user, String destination, Object payload,
@Nullable MessagePostProcessor postProcessor);
/**
* Send a message to a user-specific destination with headers and post-processor.
* @param user the user name
* @param destination the destination path
* @param payload the payload to send
* @param headers headers for the message
* @param postProcessor post-processor to apply to the message
*/
void convertAndSendToUser(String user, String destination, Object payload,
@Nullable Map<String, Object> headers,
@Nullable MessagePostProcessor postProcessor);
}Functional interface for modifying messages before sending.
/**
* A contract for processing a Message after it has been created, either
* returning a modified (effectively new) message or returning the same.
*/
@FunctionalInterface
public interface MessagePostProcessor {
/**
* Apply this post-processor to the given message.
* @param message the message to process
* @return the post-processed message (can be the same instance or a new one)
*/
Message<?> postProcessMessage(Message<?> message);
}Usage Examples:
import org.springframework.messaging.core.MessagePostProcessor;
import org.springframework.messaging.Message;
import org.springframework.messaging.support.MessageBuilder;
// Simple post-processor
MessagePostProcessor addTimestamp = message ->
MessageBuilder.fromMessage(message)
.setHeader("timestamp", System.currentTimeMillis())
.build();
// Post-processor with conditional logic
MessagePostProcessor addPriority = message -> {
Object payload = message.getPayload();
String priority = (payload instanceof UrgentMessage) ? "high" : "normal";
return MessageBuilder.fromMessage(message)
.setHeader("priority", priority)
.build();
};
// Composite post-processor
MessagePostProcessor composite = message -> {
message = addTimestamp.postProcessMessage(message);
message = addPriority.postProcessMessage(message);
return message;
};
// Use with template
template.convertAndSend("/topic/events", event, addTimestamp);
template.convertAndSend("/topic/notifications", notification, composite);
class UrgentMessage {
private String content;
public UrgentMessage(String content) { this.content = content; }
public String getContent() { return content; }
}Strategy interface for resolving destination names to destination objects.
/**
* Strategy interface for resolving a String destination name to an
* actual destination of type D.
*
* @param <D> the destination type
*/
@FunctionalInterface
public interface DestinationResolver<D> {
/**
* Resolve the given destination name.
* @param name the destination name to resolve
* @return the resolved destination
* @throws DestinationResolutionException if the specified destination wasn't found
* or wasn't resolvable for any other reason
*/
D resolveDestination(String name) throws DestinationResolutionException;
}Usage Examples:
import org.springframework.messaging.core.DestinationResolver;
import org.springframework.messaging.MessageChannel;
import org.springframework.messaging.core.GenericMessagingTemplate;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
// Custom destination resolver
DestinationResolver<MessageChannel> resolver = destinationName -> {
// Look up channel by name
MessageChannel channel = channelRegistry.get(destinationName);
if (channel == null) {
throw new DestinationResolutionException(
"No channel found for destination: " + destinationName);
}
return channel;
};
// Configure template with resolver
ExecutorSubscribableChannel defaultChannel = new ExecutorSubscribableChannel();
GenericMessagingTemplate template = new GenericMessagingTemplate(defaultChannel);
template.setDestinationResolver(resolver);
// Now can send to named destinations
template.convertAndSend("orderQueue", order);
template.convertAndSend("notificationTopic", notification);
// Bean factory based resolver (resolves from Spring context)
BeanFactoryMessageChannelDestinationResolver beanResolver =
new BeanFactoryMessageChannelDestinationResolver(beanFactory);
template.setDestinationResolver(beanResolver);
template.convertAndSend("myChannelBean", message);
Map<String, MessageChannel> channelRegistry = new ConcurrentHashMap<>();
Object order = new Object();
Object notification = new Object();
BeanFactory beanFactory = null; // Would be injected in real app
Object message = new Object();