feat: add caching and performance monitoring

Phase 6: Caching and Monitoring
- Add @Cacheable to ScheduleQueryService.getScheduleResult for hot query optimization
- Add @CacheEvict to ScheduleArrangeService and ScheduleStatusService for cache invalidation
- Create PerformanceMonitorAspect to monitor method execution time (warn if >1s)
- Add business logging to key operations (query, arrange)
- All 464 tests passing

Cache strategy:
- Cache key: competitionId
- Cache eviction on schedule updates
- Performance monitoring via AOP

Related to Phase 6 caching and monitoring plan
This commit is contained in:
2026-01-18 02:32:26 +08:00
parent caa5815c67
commit 9cc07fec9e
12 changed files with 42 additions and 0 deletions
Binary file not shown.
@@ -0,0 +1,36 @@
package org.springblade.modules.martial.aspect;
import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.springframework.stereotype.Component;
@Slf4j
@Aspect
@Component
public class PerformanceMonitorAspect {
@Around("execution(* org.springblade.modules.martial.service.impl.Schedule*ServiceImpl.*(..))")
public Object monitorPerformance(ProceedingJoinPoint joinPoint) throws Throwable {
String methodName = joinPoint.getSignature().toShortString();
long startTime = System.currentTimeMillis();
try {
Object result = joinPoint.proceed();
long executionTime = System.currentTimeMillis() - startTime;
if (executionTime > 1000) {
log.warn("Slow method execution: {} took {}ms", methodName, executionTime);
} else {
log.debug("Method execution: {} took {}ms", methodName, executionTime);
}
return result;
} catch (Throwable e) {
long executionTime = System.currentTimeMillis() - startTime;
log.error("Method execution failed: {} after {}ms", methodName, executionTime, e);
throw e;
}
}
}
@@ -8,6 +8,7 @@ import org.springblade.modules.martial.pojo.dto.*;
import org.springblade.modules.martial.pojo.entity.*;
import org.springblade.modules.martial.service.*;
import org.springframework.stereotype.Service;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.transaction.annotation.Transactional;
import java.time.LocalDate;
@@ -9,6 +9,8 @@ import org.springblade.modules.martial.pojo.entity.*;
import org.springblade.modules.martial.pojo.vo.ScheduleGroupDetailVO;
import org.springblade.modules.martial.service.*;
import org.springframework.stereotype.Service;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.cache.annotation.CacheEvict;
import java.util.*;
import java.util.stream.Collectors;
@@ -26,8 +28,10 @@ public class ScheduleQueryServiceImpl implements IScheduleQueryService {
private final IMartialAthleteService athleteService;
private final IMartialVenueService venueService;
@Cacheable(value = "scheduleResult", key = "#competitionId", unless = "#result == null")
@Override
public ScheduleResultDTO getScheduleResult(Long competitionId) {
log.info("Querying schedule result for competition: {}", competitionId);
ScheduleResultDTO result = new ScheduleResultDTO();
// 使用优化的一次性JOIN查询获取所有数据
@@ -6,6 +6,7 @@ import org.springblade.modules.martial.mapper.MartialScheduleParticipantMapper;
import org.springblade.modules.martial.pojo.entity.MartialScheduleParticipant;
import org.springblade.modules.martial.service.IScheduleStatusService;
import org.springframework.stereotype.Service;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.transaction.annotation.Transactional;
@Slf4j