feat(mq-starter-core): @MqListener 扫描 → MqListenerEndpoint
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,35 @@
|
||||
package com.njcn.mq.container;
|
||||
import com.njcn.mq.annotation.MqListener;
|
||||
import com.njcn.mq.core.MqContext;
|
||||
import org.springframework.beans.BeansException;
|
||||
import org.springframework.beans.factory.config.BeanPostProcessor;
|
||||
import org.springframework.core.annotation.AnnotatedElementUtils;
|
||||
import java.lang.reflect.Method;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
public class MqListenerAnnotationBeanPostProcessor implements BeanPostProcessor {
|
||||
|
||||
private final List<MqListenerEndpoint> endpoints = new ArrayList<>();
|
||||
public List<MqListenerEndpoint> getEndpoints() { return endpoints; }
|
||||
|
||||
@Override
|
||||
public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
|
||||
for (Method m : bean.getClass().getDeclaredMethods()) {
|
||||
MqListener meta = AnnotatedElementUtils.findMergedAnnotation(m, MqListener.class);
|
||||
if (meta == null) continue;
|
||||
Class<?>[] params = m.getParameterTypes();
|
||||
if (params.length < 1 || params.length > 2) {
|
||||
throw new IllegalStateException("@MqListener 方法签名须为 (payload) 或 (payload, MqContext): " + m);
|
||||
}
|
||||
boolean wantsContext = params.length == 2;
|
||||
if (wantsContext && params[1] != MqContext.class) {
|
||||
throw new IllegalStateException("@MqListener 第二参须为 MqContext: " + m);
|
||||
}
|
||||
Class<?> payloadType = params[0];
|
||||
m.setAccessible(true);
|
||||
endpoints.add(new MqListenerEndpoint(bean, m, meta, payloadType, wantsContext));
|
||||
}
|
||||
return bean;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,15 @@
|
||||
package com.njcn.mq.container;
|
||||
import com.njcn.mq.annotation.MqListener;
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Data;
|
||||
import java.lang.reflect.Method;
|
||||
|
||||
@Data
|
||||
@AllArgsConstructor
|
||||
public class MqListenerEndpoint {
|
||||
private Object bean;
|
||||
private Method method;
|
||||
private MqListener meta;
|
||||
private Class<?> payloadType;
|
||||
private boolean wantsContext;
|
||||
}
|
||||
@@ -0,0 +1,28 @@
|
||||
package com.njcn.mq.container;
|
||||
import com.njcn.mq.annotation.MqListener;
|
||||
import com.njcn.mq.core.MqContext;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import java.util.List;
|
||||
import static org.junit.jupiter.api.Assertions.*;
|
||||
|
||||
class MqListenerScanTest {
|
||||
static class Biz {
|
||||
@MqListener(topic = "LN_Topic", group = "ln_consumer")
|
||||
public void onData(String msg) { }
|
||||
@MqListener(topic = "T2", group = "g2")
|
||||
public void onWithCtx(String msg, MqContext ctx) { }
|
||||
}
|
||||
|
||||
@Test
|
||||
void scan_findsEndpoints_withPayloadTypeAndContextFlag() {
|
||||
MqListenerAnnotationBeanPostProcessor bpp = new MqListenerAnnotationBeanPostProcessor();
|
||||
bpp.postProcessAfterInitialization(new Biz(), "biz");
|
||||
List<MqListenerEndpoint> eps = bpp.getEndpoints();
|
||||
assertEquals(2, eps.size());
|
||||
MqListenerEndpoint e1 = eps.stream().filter(e -> e.getMeta().topic().equals("LN_Topic")).findFirst().orElseThrow(AssertionError::new);
|
||||
assertEquals(String.class, e1.getPayloadType());
|
||||
assertFalse(e1.isWantsContext());
|
||||
MqListenerEndpoint e2 = eps.stream().filter(e -> e.getMeta().topic().equals("T2")).findFirst().orElseThrow(AssertionError::new);
|
||||
assertTrue(e2.isWantsContext());
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user