작성자 : 황지성
@Target({ElementType.METHOD, ElementType.ANNOTATION_TYPE})
@Retention(RetentionPolicy.RUNTIME)
public @interface ExeTimer {
}
@PointCut을 통해 모든 JointPoint에서 적용될 Point를 지정한다. @annotation을 이용해서 작성한 어노테이션의 path를 지정한다.
@Slf4j
@Aspect
@Component
public class ExecutionTimer {
// 조인포인트를 어노테이션으로 설정
@Pointcut("@annotation(com.example.pirate99_final.global.ExeTimer)")
private void timer(){};
// 메서드 실행 전,후로 시간을 공유해야 하기 때문
@Around("timer()")
public void AssumeExecutionTime(ProceedingJoinPoint joinPoint) throws Throwable {
StopWatch stopWatch = new StopWatch();
stopWatch.start();
joinPoint.proceed(); // 조인포인트의 메서드 실행
stopWatch.stop();
long totalTimeMillis = stopWatch.getTotalTimeMillis();
MethodSignature signature = (MethodSignature) joinPoint.getSignature();
String methodName = signature.getMethod().getName();
log.info("실행 메서드: {}, 실행시간 = {}ms", methodName, totalTimeMillis);
}
}
측정하고자 하는 Method에 JointPoint를 위해 작성했던 어노테이션을 추가한다.
@ExeTimer
public MsgResponseDto enterStore(Long storeId) { // need to update
RLock lock = redissonClient.getLock("key 이름");
int availableCnt = 0; // 이용 가능 좌석
try{
boolean isLocked = lock.tryLock(10000,1000, TimeUnit.MILLISECONDS);
if(isLocked) {
try {
// 1. find store
Store store = storeRepository.findById(storeId).orElseThrow(()->
new CustomException(ErrorCode.NOT_FOUND_STORE_ERROR)
);
// 2. storeStatus check
StoreStatus storeStatus = storeStatusRepository.findByStore(store);
// 3. counting availableCnt
if((storeStatus.getAvailableTableCnt() - 1) > 0){
availableCnt = storeStatus.getAvailableTableCnt() - 1;
}
else if(storeStatus.getAvailableTableCnt() == 0){
return new MsgResponseDto(SuccessCode.NOT_ENOUGH_TABLE); // 해당 부분 수정 필요
}
// 4. update storeStatus
storeStatus.update(availableCnt);
storeStatusRepository.save(storeStatus);
return new MsgResponseDto(SuccessCode.CONFIRM_ENTER);
}catch(Exception e){
}finally{
lock.unlock();
}
}
}catch(Exception e){
Thread.currentThread().interrupt();
}
return null;
}