feat(REQ-4418) - Starter 增加 MQ 必须实现的监听
This commit is contained in:
parent
5ee919512c
commit
0860e137d3
@ -24,6 +24,7 @@ import cn.axzo.workflow.starter.mq.broadcast.consumer.InnerNotificationEventList
|
|||||||
import cn.axzo.workflow.starter.mq.broadcast.consumer.InnerTaskEventListener;
|
import cn.axzo.workflow.starter.mq.broadcast.consumer.InnerTaskEventListener;
|
||||||
import cn.axzo.workflow.starter.mq.broadcast.consumer.InnerWorkflowListener;
|
import cn.axzo.workflow.starter.mq.broadcast.consumer.InnerWorkflowListener;
|
||||||
import cn.axzo.workflow.starter.mq.check.ImplementationChecker;
|
import cn.axzo.workflow.starter.mq.check.ImplementationChecker;
|
||||||
|
import cn.axzo.workflow.starter.mq.check.ImplementationReadyChecker;
|
||||||
import cn.axzo.workflow.starter.mq.monitor.WorkflowEngineStarterDefaultMQMonitor;
|
import cn.axzo.workflow.starter.mq.monitor.WorkflowEngineStarterDefaultMQMonitor;
|
||||||
import cn.axzo.workflow.starter.mq.monitor.console.WorkflowEngineStarterMQMonitorController;
|
import cn.axzo.workflow.starter.mq.monitor.console.WorkflowEngineStarterMQMonitorController;
|
||||||
import cn.axzo.workflow.starter.selector.MetaFeignClientEnableSelector;
|
import cn.axzo.workflow.starter.selector.MetaFeignClientEnableSelector;
|
||||||
@ -161,4 +162,9 @@ public class WorkflowEngineStarterAutoConfiguration {
|
|||||||
return new ImplementationChecker();
|
return new ImplementationChecker();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Bean
|
||||||
|
public ImplementationReadyChecker implementationReadyChecker() {
|
||||||
|
return new ImplementationReadyChecker();
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@ -0,0 +1,98 @@
|
|||||||
|
package cn.axzo.workflow.starter.mq.check;
|
||||||
|
|
||||||
|
import cn.axzo.workflow.starter.handler.ProcessInstanceEventHandler;
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
import org.springframework.boot.context.event.ApplicationReadyEvent;
|
||||||
|
import org.springframework.context.ApplicationContext;
|
||||||
|
import org.springframework.context.ApplicationListener;
|
||||||
|
|
||||||
|
import java.lang.reflect.Method;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Starter MQ 监听实现检查
|
||||||
|
*
|
||||||
|
* @author wangli
|
||||||
|
* @since 2025-08-25 20:06
|
||||||
|
*/
|
||||||
|
@Slf4j
|
||||||
|
public class ImplementationReadyChecker implements ApplicationListener<ApplicationReadyEvent> {
|
||||||
|
|
||||||
|
private static final Class<ProcessInstanceEventHandler> TARGET_INTERFACE = ProcessInstanceEventHandler.class;
|
||||||
|
// 要检查的方法列表,顺序对应二进制位的位置(从左到右)
|
||||||
|
private static final List<String> METHOD_NAMES = Arrays.asList(
|
||||||
|
"onCompleted",
|
||||||
|
"onCancelled",
|
||||||
|
"onRejected",
|
||||||
|
"onAborted"
|
||||||
|
);
|
||||||
|
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onApplicationEvent(ApplicationReadyEvent event) {
|
||||||
|
ApplicationContext context = event.getApplicationContext();
|
||||||
|
// 获取所有实现了目标接口的Bean
|
||||||
|
Map<String, ProcessInstanceEventHandler> handlers = context.getBeansOfType(TARGET_INTERFACE);
|
||||||
|
if (handlers.isEmpty()) {
|
||||||
|
// 如果没有找到任何实现类,可以选择抛出异常或记录警告
|
||||||
|
log.info("未找到实现 " + TARGET_INTERFACE.getName() + " 接口的Bean, 请确保至少有一个实现类被正确扫描和注册。");
|
||||||
|
// throw new IllegalStateException("未找到实现 " + TARGET_INTERFACE.getName() + " 接口的Bean, 请确保至少有一个实现类被正确扫描和注册。");
|
||||||
|
}
|
||||||
|
|
||||||
|
// 记录每个方法是否被实现
|
||||||
|
boolean[] methodImplemented = new boolean[4];
|
||||||
|
Arrays.fill(methodImplemented, false);
|
||||||
|
|
||||||
|
// 检查每个实现类
|
||||||
|
for (ProcessInstanceEventHandler handler : handlers.values()) {
|
||||||
|
Class<?> handlerClass = handler.getClass();
|
||||||
|
|
||||||
|
// 检查每个方法是否被当前实现类覆盖
|
||||||
|
for (int i = 0; i < METHOD_NAMES.size(); i++) {
|
||||||
|
String methodName = METHOD_NAMES.get(i);
|
||||||
|
try {
|
||||||
|
Method method = handlerClass.getMethod(methodName);
|
||||||
|
// 检查方法是否来自接口本身(如果是默认方法)还是实现类
|
||||||
|
if (method.getDeclaringClass() != ProcessInstanceEventHandler.class) {
|
||||||
|
methodImplemented[i] = true;
|
||||||
|
}
|
||||||
|
} catch (NoSuchMethodException e) {
|
||||||
|
// 方法未被实现,保持默认值false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 生成4位二进制数
|
||||||
|
int binaryResult = 0;
|
||||||
|
for (int i = 0; i < methodImplemented.length; i++) {
|
||||||
|
if (methodImplemented[i]) {
|
||||||
|
// 计算当前位对应的权重(第一位是8,第二位是4,以此类推)
|
||||||
|
int weight = (int) Math.pow(2, 3 - i);
|
||||||
|
binaryResult += weight;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 收集未实现的方法
|
||||||
|
List<String> unimplementedMethods = new ArrayList<>();
|
||||||
|
for (int i = 0; i < methodImplemented.length; i++) {
|
||||||
|
if (!methodImplemented[i]) {
|
||||||
|
unimplementedMethods.add(METHOD_NAMES.get(i));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
log.info("实现 {} 接口的Bean数量: {}", TARGET_INTERFACE.getName(), handlers.size());
|
||||||
|
log.info("方法实现情况:(二进制:{}),(十进制:{})", String.format("%4s", Integer.toBinaryString(binaryResult)).replace(' ', '0'), binaryResult);
|
||||||
|
if (!unimplementedMethods.isEmpty()) {
|
||||||
|
log.info("以下方法未被任何实现类覆盖: " + String.join(", ", unimplementedMethods) +
|
||||||
|
"。请确保至少有一个实现类覆盖这些方法以处理相应的事件。");
|
||||||
|
// throw new IllegalStateException("以下方法未被任何实现类覆盖: " + String.join(", ", unimplementedMethods) +
|
||||||
|
// "。请确保至少有一个实现类覆盖这些方法以处理相应的事件。");
|
||||||
|
} else {
|
||||||
|
log.info("Congratulations, passed the verification!");
|
||||||
|
log.info("祝贺,已通过校验!");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
Loading…
Reference in New Issue
Block a user