Skip to content

Commit 298997b

Browse files
committed
Optimize getMessageType and getMethodParameter methods in DefaultRocketMQListenerContainer
1 parent c1dbf87 commit 298997b

File tree

2 files changed

+28
-44
lines changed

2 files changed

+28
-44
lines changed

rocketmq-spring-boot/src/main/java/org/apache/rocketmq/spring/support/DefaultRocketMQListenerContainer.java

Lines changed: 21 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -20,9 +20,11 @@
2020
import java.lang.reflect.Method;
2121
import java.lang.reflect.ParameterizedType;
2222
import java.lang.reflect.Type;
23+
import java.lang.reflect.TypeVariable;
2324
import java.nio.charset.Charset;
2425
import java.util.List;
2526
import java.util.Objects;
27+
2628
import org.apache.rocketmq.client.AccessChannel;
2729
import org.apache.rocketmq.client.consumer.DefaultMQPushConsumer;
2830
import org.apache.rocketmq.client.consumer.MessageSelector;
@@ -58,6 +60,7 @@
5860
import org.springframework.context.ApplicationContextAware;
5961
import org.springframework.context.SmartLifecycle;
6062
import org.springframework.core.MethodParameter;
63+
import org.springframework.core.ResolvableType;
6164
import org.springframework.messaging.Message;
6265
import org.springframework.messaging.MessageHeaders;
6366
import org.springframework.messaging.converter.MessageConversionException;
@@ -66,6 +69,7 @@
6669
import org.springframework.messaging.support.MessageBuilder;
6770
import org.springframework.util.Assert;
6871
import org.springframework.util.MimeTypeUtils;
72+
import org.springframework.util.ReflectionUtils;
6973

7074
@SuppressWarnings("WeakerAccess")
7175
public class DefaultRocketMQListenerContainer implements InitializingBean,
@@ -538,6 +542,8 @@ private Object doConvertMessage(MessageExt messageExt) {
538542
if (messageType instanceof Class) {
539543
//if the messageType has not Generic Parameter
540544
return this.getMessageConverter().fromMessage(MessageBuilder.withPayload(str).build(), (Class<?>) messageType);
545+
} else if (messageType instanceof TypeVariable) {
546+
return this.getMessageConverter().fromMessage(MessageBuilder.withPayload(str).build(), Object.class);
541547
} else {
542548
//if the messageType has Generic Parameter, then use SmartMessageConverter#fromMessage with third parameter "conversionHint".
543549
//we have validate the MessageConverter is SmartMessageConverter in this#getMethodParameter.
@@ -553,61 +559,37 @@ private Object doConvertMessage(MessageExt messageExt) {
553559

554560
private MethodParameter getMethodParameter() {
555561
Class<?> targetClass;
562+
Class<?> consumerInterface;
556563
if (rocketMQListener != null) {
557564
targetClass = AopProxyUtils.ultimateTargetClass(rocketMQListener);
565+
consumerInterface = RocketMQListener.class;
558566
} else {
559567
targetClass = AopProxyUtils.ultimateTargetClass(rocketMQReplyListener);
568+
consumerInterface = RocketMQReplyListener.class;
560569
}
561-
Type messageType = this.getMessageType();
562-
Class clazz = null;
563-
if (messageType instanceof ParameterizedType && messageConverter instanceof SmartMessageConverter) {
564-
clazz = (Class) ((ParameterizedType) messageType).getRawType();
565-
} else if (messageType instanceof Class) {
566-
clazz = (Class) messageType;
567-
} else {
568-
throw new RuntimeException("parameterType:" + messageType + " of onMessage method is not supported");
569-
}
570-
try {
571-
final Method method = targetClass.getMethod("onMessage", clazz);
572-
return new MethodParameter(method, 0);
573-
} catch (NoSuchMethodException e) {
574-
e.printStackTrace();
575-
throw new RuntimeException("parameterType:" + messageType + " of onMessage method is not supported");
576-
}
570+
ResolvableType resolvableType = ResolvableType.forClass(targetClass).as(consumerInterface);
571+
Class<?> methodParameterType = resolvableType.getGeneric().resolve(Object.class);
572+
Method onMessage = ReflectionUtils.findMethod(targetClass, "onMessage", methodParameterType);
573+
return MethodParameter.forExecutable(onMessage, 0);
577574
}
578575

576+
579577
private Type getMessageType() {
580578
Class<?> targetClass;
579+
Class<?> consumerInterface;
581580
if (rocketMQListener != null) {
582581
targetClass = AopProxyUtils.ultimateTargetClass(rocketMQListener);
582+
consumerInterface = RocketMQListener.class;
583583
} else {
584584
targetClass = AopProxyUtils.ultimateTargetClass(rocketMQReplyListener);
585+
consumerInterface = RocketMQReplyListener.class;
585586
}
586-
Type matchedGenericInterface = null;
587-
while (Objects.nonNull(targetClass)) {
588-
Type[] interfaces = targetClass.getGenericInterfaces();
589-
if (Objects.nonNull(interfaces)) {
590-
for (Type type : interfaces) {
591-
if (type instanceof ParameterizedType &&
592-
(Objects.equals(((ParameterizedType) type).getRawType(), RocketMQListener.class) || Objects.equals(((ParameterizedType) type).getRawType(), RocketMQReplyListener.class))) {
593-
matchedGenericInterface = type;
594-
break;
595-
}
596-
}
597-
}
598-
targetClass = targetClass.getSuperclass();
599-
}
600-
if (Objects.isNull(matchedGenericInterface)) {
601-
return Object.class;
602-
}
603-
604-
Type[] actualTypeArguments = ((ParameterizedType) matchedGenericInterface).getActualTypeArguments();
605-
if (Objects.nonNull(actualTypeArguments) && actualTypeArguments.length > 0) {
606-
return actualTypeArguments[0];
607-
}
608-
return Object.class;
587+
ResolvableType resolvableType = ResolvableType.forClass(targetClass).as(consumerInterface);
588+
Type messageType = resolvableType.getGeneric().getType();
589+
return messageType;
609590
}
610591

592+
611593
private void initRocketMQPushConsumer() throws MQClientException {
612594
if (rocketMQListener == null && rocketMQReplyListener == null) {
613595
throw new IllegalArgumentException("Property 'rocketMQListener' or 'rocketMQReplyListener' is required");

rocketmq-spring-boot/src/test/java/org/apache/rocketmq/spring/support/DefaultRocketMQListenerContainerTest.java

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,7 @@
4848
import static org.assertj.core.api.Assertions.assertThat;
4949
import static org.junit.Assert.assertEquals;
5050
import static org.mockito.ArgumentMatchers.any;
51+
import static org.mockito.ArgumentMatchers.nullable;
5152
import static org.mockito.Mockito.doNothing;
5253
import static org.mockito.Mockito.mock;
5354
import static org.mockito.Mockito.when;
@@ -65,7 +66,7 @@ public void onMessage(String message) {
6566
}
6667
});
6768
Class result = (Class) getMessageType.invoke(listenerContainer);
68-
assertThat(result.getName().equals(String.class.getName()));
69+
assertEquals(result, String.class);
6970

7071
//support message
7172
listenerContainer.setRocketMQListener(new RocketMQListener<Message>() {
@@ -74,16 +75,17 @@ public void onMessage(Message message) {
7475
}
7576
});
7677
result = (Class) getMessageType.invoke(listenerContainer);
77-
assertThat(result.getName().equals(Message.class.getName()));
78+
assertEquals(result, Message.class);
7879

7980
listenerContainer.setRocketMQListener(new RocketMQListener<MessageExt>() {
8081
@Override
8182
public void onMessage(MessageExt message) {
8283
}
8384
});
8485
result = (Class) getMessageType.invoke(listenerContainer);
85-
assertThat(result.getName().equals(MessageExt.class.getName()));
86+
assertEquals(result, MessageExt.class);
8687

88+
listenerContainer.setRocketMQListener(null);
8789

8890
listenerContainer.setRocketMQReplyListener(new RocketMQReplyListener<MessageExt, String>() {
8991
@Override
@@ -92,7 +94,7 @@ public String onMessage(MessageExt message) {
9294
}
9395
});
9496
result = (Class) getMessageType.invoke(listenerContainer);
95-
assertThat(result.getName().equals(MessageExt.class.getName()));
97+
assertEquals(result, MessageExt.class);
9698

9799
listenerContainer.setRocketMQReplyListener(new RocketMQReplyListener<String, String>() {
98100
@Override
@@ -101,7 +103,7 @@ public String onMessage(String message) {
101103
}
102104
});
103105
result = (Class) getMessageType.invoke(listenerContainer);
104-
assertThat(result.getName().equals(String.class.getName()));
106+
assertEquals(result, String.class);
105107
}
106108

107109
@Test

0 commit comments

Comments
 (0)