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:
@@ -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());
|
||||
});
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user