feat: 添加AOP支持和更新链接控制器逻辑

主要修改:
1. 在pom.xml中新增spring-boot-starter-aop依赖,支持面向切面编程。
2. 在LinkController中移除DeviceCodeMappingService的依赖,更新二维码获取逻辑,使用linkStatusService获取设备ID。
3. 在SelectRegionResponse中新增mecmachineId字段,便于调试和维护。
4. 在SecurityConfig中允许二维码HEAD请求公开访问。

技术细节:
- 通过引入AOP支持,提升了代码的可维护性和扩展性,同时优化了链接控制器的逻辑,确保设备ID的获取更加灵活。
This commit is contained in:
zyh
2025-08-28 22:19:06 +08:00
parent a56eebc30b
commit 1d72bc4c5a
12 changed files with 526 additions and 352 deletions

View File

@@ -0,0 +1,81 @@
package com.gameplatform.server.aspect;
import com.gameplatform.server.annotation.RepeatCall;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;
import reactor.core.publisher.Mono;
/**
* 重复调用切面
* 处理被 @RepeatCall 注解标记的方法,实现重复执行逻辑
* 目前主要支持返回 Mono 类型的方法
*/
@Aspect
@Component
public class RepeatCallAspect {
private static final Logger log = LoggerFactory.getLogger(RepeatCallAspect.class);
@Around("@annotation(repeatCall)")
public Object repeatCall(ProceedingJoinPoint joinPoint, RepeatCall repeatCall) throws Throwable {
String methodName = joinPoint.getSignature().getName();
String className = joinPoint.getTarget().getClass().getSimpleName();
int times = repeatCall.times();
String description = repeatCall.description().isEmpty() ? methodName : repeatCall.description();
log.info("开始重复调用: {}.{} - {} (将执行{}次)", className, methodName, description, times);
// 执行第一次调用
Mono<Object> currentCall = executeOnce(joinPoint, className, methodName, description, 1);
// 链式执行后续调用
for (int i = 2; i <= times; i++) {
final int attemptNumber = i;
currentCall = currentCall
.onErrorReturn("" + (attemptNumber - 1) + "次调用失败")
.flatMap(result -> {
log.debug("第{}次调用完成,准备执行第{}次", attemptNumber - 1, attemptNumber);
return executeOnce(joinPoint, className, methodName, description, attemptNumber);
});
}
return currentCall
.onErrorReturn("最后一次调用失败")
.doOnSuccess(finalResult -> {
log.info("重复调用全部完成: {}.{} - {} (执行了{}次), 最终结果={}",
className, methodName, description, times, finalResult);
});
}
/**
* 执行单次调用
*/
private Mono<Object> executeOnce(ProceedingJoinPoint joinPoint, String className,
String methodName, String description, int attemptNumber) {
return Mono.defer(() -> {
try {
Object result = joinPoint.proceed();
if (result instanceof Mono) {
return ((Mono<?>) result).cast(Object.class);
} else {
return Mono.just(result);
}
} catch (Throwable throwable) {
return Mono.error(throwable);
}
})
.doOnSuccess(result -> {
log.debug("重复调用第{}次成功: {}.{} - {}, 结果={}",
attemptNumber, className, methodName, description, result);
})
.doOnError(error -> {
log.warn("重复调用第{}次失败: {}.{} - {}, 错误={}",
attemptNumber, className, methodName, description, error.toString());
});
}
}