You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@rocketmq.apache.org by "muzhi9018 (via GitHub)" <gi...@apache.org> on 2025/01/25 05:47:42 UTC
[I] Cannot implement parent class encapsulation to handle the same business logic in a unified way [rocketmq-spring]
muzhi9018 opened a new issue, #704:
URL: https://github.com/apache/rocketmq-spring/issues/704
I want to realize that sending a message is passing the current login context information to the message consumer
```java
// This is the code for the parent class
public abstract class BaseMQConsumer<T extends MQMessage> {
/**
* Used to store the user who sent the current message
*/
private static final ThreadLocal<User> SEND_MSG_USER = new ThreadLocal<>();
/**
* Enhancements to the default message listener methods to set the global user that sends the current message.
*/
public final void onMessage(T message) {
try {
SEND_MSG_USER.set(message.getUser());
this.onMessage(message, message.getUser());
} finally {
SEND_MSG_USER.remove();
}
}
/**
* Execute the onMessage method
* @param message Original message
* @param sendMsgUser The user who sent the current message
*/
public abstract void onMessage(T message, User sendMsgUser);
/**
* Get the user who sent the current message
*/
public final User getCurrentUser() {
return SEND_MSG_USER.get();
}
}
```
```java
// Here's the code for the subclass
@Slf4j
@Component
@RequiredArgsConstructor
@RocketMQMessageListener(consumerGroup = "${rocketmq.group}" + "-group-sync-order", topic = "${rocketmq.group}" + MqTopic.SYNC_ORDER_TOPIC, consumeMode = ConsumeMode.ORDERLY)
public class TmsSyncOrderConsumer extends BaseMQConsumer<SonMQMessage> implements RocketMQListener<SonMQMessage> {
private final RedisTemplate<String, String> redisTemplate;
@Override
public void onMessage(SonMQMessage message, User sendMsgUser) {
User currentUser = SecurityUtils.getCurrentUser();
String msgText = message.getMsgText();
SysOrderVO sysOrderVO = JSON.parseObject(msgText, SysOrderVO.class);
try {
log.info("[onMessage] message:{}, sendMsgUser:{}, currentUser:{}", message, sendMsgUser, currentUser);
} finally {
RedisKey redisKey = RedisKey.STORE_SYNC_ORDER_LOCK;
String key = redisKey.getKey(sysOrderVO.getShopId());
redisTemplate.delete(key);
}
}
}
```
```java
// This is the parent message object
@Getter
@Setter
public class MQMessage implements Serializable {
private static final long serialVersionUID = 1463117417381786448L;
private User user;
public MQMessage() {
this.user = SecurityUtils.getCurrentUser();
}
private String msgId;
private Integer msgType;
private String msgText;
private Long channelInfoId;
}
```
```java
// This is the subclass message object
public class SonMQMessage extends MQMessage {
private static final long serialVersionUID = -6645128888099960442L;
private String username;
}
```
Running error: Initialization of bean failed; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'org.apache.rocketmq.spring.support.DefaultRocketMQListenerContainer_5': Invocation of init method failed; nested exception is java.lang.RuntimeException: parameterType:class com.shenzhen.common.rocketmq.model.SonMQMessage of onMessage method is not supported
But I have implemented the onMessage method in the parent class. It's just that my parameter type is dynamic
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: commits-unsubscribe@rocketmq.apache.org.apache.org
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
Re: [I] Cannot implement parent class encapsulation to handle the same business logic in a unified way [rocketmq-spring]
Posted by "RockteMQ-AI (via GitHub)" <gi...@apache.org>.
RockteMQ-AI commented on issue #704:
URL: https://github.com/apache/rocketmq-spring/issues/704#issuecomment-5216242995
**Issue Evaluation**
Category: `question` | Status: **Answered**
The `RocketMQMessageListener` annotation uses Spring's generic type resolution to determine the message type for deserialization. When you extend a base class and implement `RocketMQListener<T>`, the framework resolves the generic type from the concrete class, not the parent class.
The issue in your code is that `BaseMQConsumer<T>` defines `onMessage(T message)` but the framework's `DefaultRocketMQListenerContainer` calls `RocketMQListener.onMessage()` directly — your parent class `onMessage(T)` shadows the interface method, causing the framework to bypass your context-setting logic.
**Suggested approach:**
- Instead of overriding `onMessage` in the parent class, use a custom `RocketMQListener` wrapper or AOP to inject the context before the actual listener processes the message.
- Alternatively, handle context propagation in each consumer's `onMessage` implementation directly.
This is a known limitation of the annotation-driven approach — it does not support inheritance-based message interception.
---
*Automated evaluation by @RockteMQ-AI*
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: commits-unsubscribe@rocketmq.apache.org
For queries about this service, please contact Infrastructure at:
users@infra.apache.org