작성자 : 황지성

AOP를 위한 JointPoint용 어노테이션 작성

@Target({ElementType.METHOD, ElementType.ANNOTATION_TYPE})
@Retention(RetentionPolicy.RUNTIME)
public @interface ExeTimer {
}

AOP 클래스 작성

@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 적용

측정하고자 하는 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;
}