Message Properties
IntermediateAMQP properties include delivery-mode (persistent/transient), content-type, correlation-id, reply-to, expiration, headers, and priority — all set by the producer per message.
Overview
Every AMQP message carries a set of well-known properties in its envelope header. The most important are delivery-mode (1=transient, 2=persistent), content-type (e.g. "application/json"), content-encoding, correlation-id (links a response to a request in RPC), reply-to (name of the queue to send the response to), message-id (publisher-assigned unique ID), expiration (per-message TTL in milliseconds as a string), priority (0-9 for priority queues), and user-defined headers (Map<String,Object>). In Spring AMQP, MessageProperties encapsulates all of these, and MessagePostProcessors let you set them per-send without modifying the payload.
Setting Message Properties
Use a MessagePostProcessor in convertAndSend to set properties on each message. For consistent defaults across an application, configure a MessagePropertiesConverter on the RabbitTemplate.
rabbitTemplate.convertAndSend("orders", "order.created", event, message -> {
MessageProperties props = message.getMessageProperties();
props.setDeliveryMode(MessageDeliveryMode.PERSISTENT); // survive restart
props.setContentType("application/json");
props.setMessageId(UUID.randomUUID().toString());
props.setCorrelationId(requestContext.getTraceId());
props.setExpiration("60000"); // 60s per-message TTL
props.setHeader("source-service", "order-service");
props.setHeader("schema-version", "2");
return message;
});RPC Pattern with correlation-id and reply-to
correlation-id and reply-to are the two properties that power the RPC pattern. The caller sets reply-to to its exclusive reply queue, and correlation-id to a unique request ID. The server echoes the correlation-id in its response so the caller can match it.
// Caller side
String correlationId = UUID.randomUUID().toString();
String replyQueueName = "rpc.reply." + correlationId;
rabbitTemplate.convertAndSend("rpc.requests", "", request, msg -> {
msg.getMessageProperties().setCorrelationId(correlationId);
msg.getMessageProperties().setReplyTo(replyQueueName);
return msg;
});
// Server side — echo correlation-id in response
@RabbitListener(queues = "rpc.requests")
public void handleRequest(Message request, Channel channel) throws Exception {
String replyTo = request.getMessageProperties().getReplyTo();
String correlationId = request.getMessageProperties().getCorrelationId();
// ... process ...
rabbitTemplate.convertAndSend(replyTo, response, msg -> {
msg.getMessageProperties().setCorrelationId(correlationId);
return msg;
});
}Reading Properties on Consumer Side
In @RabbitListener methods, inject Message to access the full AMQP envelope including all properties and headers. Use @Header to extract individual header values directly.
@RabbitListener(queues = "orders.processing")
public void onOrder(
OrderEvent event,
@Header("source-service") String sourceService,
@Header(AmqpHeaders.CORRELATION_ID) String correlationId,
@Header(AmqpHeaders.RECEIVED_ROUTING_KEY) String routingKey,
Message rawMessage) {
log.info("Source: {}, correlationId: {}, routingKey: {}",
sourceService, correlationId, routingKey);
// Full access to all properties
MessageProperties props = rawMessage.getMessageProperties();
String messageId = props.getMessageId();
String contentType = props.getContentType();
}Key Points to Remember
- 1delivery-mode=2 (PERSISTENT) is required for messages to survive broker restart
- 2correlation-id + reply-to together implement the RPC/request-reply pattern
- 3expiration is per-message TTL in milliseconds as a String (independent of queue x-message-ttl)
- 4headers is a Map<String,Object> for arbitrary application-level metadata
- 5priority (0-9) is honoured only if the queue was declared with x-max-priority argument
- 6Use @Header annotation in @RabbitListener to extract individual properties cleanly
Interview Questions
Sign in to ask AriaWhat are the two message properties used to implement the RPC pattern?
What is the difference between per-message expiration and queue x-message-ttl?
How do you set consistent default properties for all messages sent via RabbitTemplate?
What delivery-mode value makes a message persistent?
How would you pass trace/correlation IDs through RabbitMQ for distributed tracing?
Ask Aria about Message Properties
Your personal AI tutor — ask anything about this concept
Revision Status
Personal Notes
Sign in to save personal notes for this topic.
Discussion
Sign in to join the discussion.