前情提要:新增任务、更换人员、安排人员时,会检测冲突,并提供解决冲突的入口,这个需求是后续添加的,为了不变动现有接口的入参,实现代码解耦,我使用了自定义注解 AOP实现需求。

注解接口
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface HttpServletRequestParamLogger {
String notes() default "";
}
注解Aspect
@Slf4j
@Aspect
@Component
public class HttpServletRequestParamLoggerAspect {
@Autowired
private WsbJobScheduleDataService wsbJobScheduleDataService;
@Autowired
private WsbJobSchedulingService wsbJobSchedulingService;
@Autowired
private WsbJobScheduleParamsService wsbJobScheduleParamsService;
@Autowired
private RedisUtil redisUtil;
@Autowired
private WsbFlightJobService wsbFlightJobService;
@Autowired
private WsoWorkerJobInfoService wsoWorkerJobInfoService;
@Autowired
private WebSocketService webSocketService;
@AfterReturning(pointcut = "@annotation(com.eunitedtech.automatic.annotation.HttpServletRequestParamLogger)",
returning = "returnValue")
public void logHttpServletRequestParams(JoinPoint joinPoint, Object returnValue) {
ServletRequestAttributes attributes = (ServletRequestAttributes)RequestContextHolder.getRequestAttributes();
CompletableFuture.runAsync(() -> {
try {
if (attributes != null) {
HttpServletRequest request = attributes.getRequest();
String isResolvedStr = request.getParameter("isResolved");
String jobCodeStr = request.getParameter("jobCodeStr");
String redisKey = request.getParameter("redisKey");
if (ObjUtil.isNotEmpty(isResolvedStr)) {
boolean isResolved = Boolean.parseBoolean(isResolvedStr);
if (isResolved) {
log.info("解决冲突");
if (ObjUtil.isNotEmpty(jobCodeStr)) {
List<String> jobCodes = StrSplitter.splitTrim(jobCodeStr, ",", true);
WsbJobScheduling scheduling = wsbJobSchedulingService.getByJobCode(jobCodes.get(0));
Set<Object> jobIds = redisUtil.zRange(String.format(RedisConstant.REDIS_SOLVE_CONFLICT_KEY, redisKey), 0, -1);
if (CollUtil.isNotEmpty(jobIds)) {
WsbJobScheduleParams params = wsbJobScheduleParamsService.getUsedByJobSchedulingId(scheduling.getGuid());
if (ObjectUtil.isNull(params)) {
throw new BusinessException("该任务未配置智能调度参数");
}
Long scheduleTime = wsbJobScheduleParamsService.getLastTime(scheduling.getGuid());
log.info("redis中存入的taskIds:{}", jobIds);
List<String> jobIdList = jobIds.stream().map(Object::toString).collect(Collectors.toList());
Long endTime;
WsbFlightJob flightJob = wsbFlightJobService.lambdaQuery().eq(WsbFlightJob::getGuid, jobIdList.get(0)).one();
if (ObjUtil.isNull(flightJob)) {
return;
} else {
endTime = flightJob.getPlanEndTime() == null || flightJob.getPlanEndTime() <= scheduleTime ? scheduleTime : flightJob.getPlanEndTime();
}
ScheduleReqVO vo = new ScheduleReqVO().setJobSchedulingId(scheduling.getGuid())
.setTaskScheduleParams(params).setIsDropTask(true).setAutoSelect(true)
.setDataSource(ScheduleSourceEnum.MANUAL_SOLVE_CONFLICT.getSource())
.setIsResolveConflict(false).setIsMinAdjust(true)
.setJobCodes(scheduling.getJobList())
.setSolveConflictTasks(new HashSet<>(jobIdList))
.setPriority(TaskPriorityEnum.PRIORITY_TOP.getPriority()).setEndTime(endTime);
log.info("执行解决冲突方法");
ScheduleVO result = wsbJobScheduleDataService.handleAutoSchedule(vo);
ScheduleStatusVO statusVO = null;
try {
do {
statusVO = wsbJobScheduleDataService.queryState(result.getScheduleId());
} while (statusVO == null || (!ObjUtil.equals(ScheduleStateEnum.SUCCESS.getCode(), statusVO.getStatus())
&& !ObjUtil.equals(ScheduleStateEnum.FAIL.getCode(), statusVO.getStatus())));
} catch (Exception e) {
}
WsoWorkerJobInfo workerJobInfo = wsoWorkerJobInfoService.lambdaQuery()
.eq(WsoWorkerJobInfo::getFlightJobId, flightJob.getGuid()).one();
if (ObjUtil.isNotEmpty(workerJobInfo)) {
String operationMsg = String.format("将%s航班任务分配到人员%s上", flightJob.getFlightCombinationNo(),
UserHelper.getWorkName(workerJobInfo.getWorkerCode()));
statusVO.setOperationMsg(operationMsg);
}
webSocketService.sendMessage(new MessageVO<ScheduleStatusVO>().setBody(statusVO).setType(MessageTypeEnum.resolveConflicts));
log.info("解决冲突执行结束");
}
}
}
}
}
} catch (Exception e) {
log.error("Error logging request parameters: {}", e.getMessage());
}
}, Executors.newVirtualThreadPerTaskExecutor());
}
@AfterThrowing(pointcut = "@annotation(com.eunitedtech.automatic.annotation.HttpServletRequestParamLogger)",
throwing = "exception")
public void handleException(JoinPoint joinPoint, Exception exception) {
log.error("异常信息:" + exception.getMessage());
}
}
注解的调用 (在controller层的方法上调用)
@HttpServletRequestParamLogger(notes = "解决冲突")
@Operation(summary = "新增任务", description = "新增任务")
@PostMapping(value = "/addTask")
public Result addTask(@Validated @NotEmpty(message = "任务信息不能为空") @RequestBody List<AddFlightTaskVO> vos, @CurrentUser LoginUser user) {
}
结语: 随手小记,欢迎评论区讨论