- Dependency Setup
To begin, include the starter dependency in your Maven project:
<dependency>
<groupId>org.apache.rocketmq</groupId>
<artifactId>rocketmq-spring-boot-starter</artifactId>
<version>2.2.3</version>
</dependency>
This dependency triggers Spring Boot’s auto-configuration system, eliminating the need for manual bean declarations.
- Message Producer Configuration
Configure the RocketMQ name server and producer group in application.yml:
rocketmq:
name-server: 127.0.0.1:9876
producer:
group: sms-producer-group
topic: sms-events-topic
Inject the RocketMQTemplate into your service component:
@Autowired
private RocketMQTemplate messageSender;
@Value("${rocketmq.topic}")
private String eventTopic;
Send messages using one of several strategies:
syncSend()— blocking, ensures delivery confirmationasyncSend()— non-blocking, callback-basedsendOneWay()— fire-and-forgetsyncSendOrderly()— ordered delivery per message key
Here’s an example of synchronous message transmission with custom headers:
String target = StringUtils.isNotBlank(tags) ?
eventTopic + ":" + tags : eventTopic;
SendResult result = messageSender.syncSend(
target,
MessageBuilder.withPayload(userEvent)
.setHeader(MessageConst.PROPERTY_KEYS, eventId)
.build()
);
if (SendStatus.SEND_OK.equals(result.getSendStatus())) {
// Log success or trigger downstream logic
}
The MessageBuilder utility constructs messages adhering to Spring’s Message contract, which the template internally converts into RocketMQ’s native Message object.
- Message Consumer Implementation
Consumer configuration is equally straightforward:
rocketmq:
name-server: 127.0.0.1:9876
consumer:
group: sms-consumer-group
topic: sms-events-topic
Define a consumer using the @RocketMQMessageListener annotation:
@Component
@RocketMQMessageListener(
consumerGroup = "${rocketmq.consumer.group}",
topic = "${rocketmq.consumer.topic}"
)
public class EventConsumer implements RocketMQListener<UserEvent> {
@Override
public void onMessage(UserEvent payload) {
System.out.println("Processing event: " + payload.getId());
// Business logic here
}
}
For advanced use cases, implement RocketMQListener<MessageExt> to access raw metadata:
@Override
public void onMessage(MessageExt rawMessage) {
try {
String body = new String(rawMessage.getBody(), StandardCharsets.UTF_8);
String key = rawMessage.getKeys();
String tag = rawMessage.getTags();
// Inspect headers, timestamp, queue ID, etc.
} catch (Exception e) {
log.error("Failed to process raw message", e);
}
}
- Project Structure Overview
The rocketmq-spring project is modularized into four key components:
- rocketmq-spring-boot-parent — manages dependency versions
- rocketmq-spring-boot — core auto-configuration logic
- rocketmq-spring-boot-starter — minimal facade for end users
- rocketmq-spring-boot-samples — practical usage examples
The samples module is indispensable for understanding real-world patterns and edge-case handling.
- Auto-Configuration Deep Dive
Spring Boot starters require three core elements:
- Declaration of required dependencies (RocketMQ client, Spring context)
- A
spring.factoriesfile underMETA-INFthat declares auto-configuration classes:
org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
org.apache.rocketmq.spring.autoconfigure.RocketMQAutoConfiguration
- An
@Configuration-annotated class that initializes beans conditionally.
In RocketMQAutoConfiguration, two key beans are created:
RocketMQTemplate— wraps producer and consumer logicDefaultRocketMQListenerContainer— manages message listener lifecycle
The template internally wraps RocketMQ’s DefaultMQProducer and LitePullConsumer (optimized for batch consumption). It handles the translation between Spring’s Message interface and RocketMQ’s native model.
For consumers, the framework registers a BeanPostProcessor that scans for classes annotated with @RocketMQMessageListener. For each annotated listener, it dynamically creates a container instance that:
- Resolves the target topic and group from property placeholders
- Determines the method signature of
onMessage()to infer expected payload type - Wraps the native
MessageExtin a conversion layer before invoking the user’s method
The critical conversion logic:
Object converted = doConvertMessage(messageExt);
rocketMQListener.onMessage(converted);
The doConvertMessage() method uses Spring’s ConversionService to transform byte[] into String, Serializable, or custom POJOs based on the listener’s method signature — enabling seamless type-safe consumption without manual deserialization.
- Design Insights and Extensibility
The rocketmq-spring project exemplifies modern Spring Boot starter design:
- Convention over configuration — minimal YAML settings replace boilerplate code
- Type-safe abstraction — developers work with domain objects, not raw bytes
- Extensible via interfaces — support for multiple payload types without breaking changes
- Separation of concerns — core logic, starter facade, and samples are decoupled
By studying this implementation, you can replicate its pattern to build your own Spring Boot starter for any messaging system — whether Kafka, RabbitMQ, or a proprietary protocol — by following the same structure: auto-configuration, property binding, container lifecycle management, and type conversion.