Spring & Java
AOP 구현 본문

이번 시간에는 AOP를 구현해 볼 것입니다.
강의를 시작하기전에 우선 AOP 어노테이션이 뭔지 알고 가야 학습에 도움이 되겠죠 ?
이게 언제 사용 되는건지 어떻게 사용 되는 것인지 확인해보겠습니다.
@Aspect, @Around, @Before 등을 활용하여 횡단 관심사 로직을 분리합니다.
AOP가 필요한 이유 ! : AOP는 Interceptor 보다 사용 빈도가 높습니다.


public String createPost(String title, String content) {
long start = System.currentTimeMillis(); // 1. 실행 시간 측정
log.info("Start creating post");
// 핵심 로직
postRepository.save(new Post(title, content));
long end = System.currentTimeMillis(); // 2. 실행 시간 측정
log.info("End creating post. Time: {}ms", end - start);
}
예를 들어, 모든 서비스 마다 '시작 시간' 과 '종료 시간'을 남기는 기능을 추가해달라고 했다면
우리는 한 메서드 마다 관리를 하게 된다면 지옥이 시작 되는겁니다. 유지보수는 더 지옥이 되겠죠?
그래서 AOP를 사용하게 되는겁니다.

public String createPost(String title, String content) {
postRepository.save(new Post(title, content));
}
AOP가 가로로 횡단 하는 식으로 도입이 될수 있습니다. AOP를 정해 놓고 시작하는 시점을 지정할 수 있게 됩니다.
가로로 일괄적용 시킬수 있어서 " 횡단 관심사 " 라고도 합니다.
-> 시간 측정은 AOP가 알아서 처리 해준다!
AOP 개념
- AOP도 처음부터 구현할 필요 없이 이미 만들어져 있고 이를 사용법대로 사용하면 됩니다.
AOP에서 사용하는 용어 모음 ( 엄청 많지만 꼭 필요한 것들만 뽑아 왔다 ! )

AOP 팁
● 어떤 것을
○ Pointcut을 통해서 대상을 지정해줍니다.
● 언제
○ Advice를 통해서 실행되는 시점을 지정해줍니다.
● 어떻게
○ Aspect 에 정의한 메서드를 통해서 어떻게 할 것인지 지정해줍니다.

AOP 활용 예시

실습 : 실행 시간 측정 AOP 만들기

기본 셋팅입니다. COMMON > aspact > TimeCheckAop 이제 여기다가 AOP 파일들을 넣어줄 생각입니다.
저는 메서드마다 얼마나 걸리는지 시간 측정 AOP를 만들 생각입니다.
TimeCheckAop 이 클래스가 AOP라는 클래스로 선언 하는 어노테이션
@Aspect @Component @Slf4j 사용합니다.
어노테이션을 선언해주고 AOP는 어떻게 사용하는지 3가지만 기억하면 됩니다!!
어떤것을, 언제, 어떻게

메서드를 하나 만들어줍니다.

@Around 어노테이션 : 메서드 실행 전후 제어
대상을 지정 합니다 execution : 우리가 지정할 대상 패키지 파일 경로를 복사합니다.
com.example.advance.user.service;
그리고 위 이미지 처럼 넣으면 됩니다. ( 와일드 카드 사용 )
UserService 하위에 모든 메서드들을 대상으로 하겠다는 뜻입니다.

대상이 잘 지정 됐는지 확인 할려면 왼쪽 m버튼을 눌러서 확인해보면 됩니다.
어떤가요? 하위 메서드들이 잘 불러 와지나요? 다른 Service가 있다면 넣어서 테스트 해보셔도 좋습니다.
@Around("execution(* com.example.advance.user.service.UserService.*(..))") // 대상을 지정해야 됩니다. 이거 좀 신기한 기능이네.
public Object executionTime(ProceedingJoinPoint joinPoint) throws Throwable {
// 메서드 실행 전
long start = System.currentTimeMillis();
Object result = joinPoint.proceed(); // 실제 메서드 실행 -> Filter의 doFilter라고 생각하면 된다.
// 메서드 실행 후
long end = System.currentTimeMillis();
log.info("[AOP] {} 실행됨 in {} ms", joinPoint.getSignature().getName(), end - start);
return result;
}
}
전체적으로 long 타입을 사용해서 메서드 실행 전에 시간을 체크하고 메서드 실행 후의 시간을 체크해서 로그로 확인 해볼 생각 입니다. 이 내용은 실행 시간 측정 AOP 만들기 핵심이라고 생각하면 되겠습니다.
이제 디버깅 모드로 눈으로 한번 봅시다! 각각 변수에 어떤 값들을 담고 있고 도대체 JoinPoint안에는 어떤 값들이 들어 있는지 눈으로 보겠습니다.
일단 ..
// 로그인 인증/인가를 Filter에서 처리 ( 첫번째 )
// Interceptor을 받아서 통과를 했다면
// UserEmailUpdate 메서드는 AOP 수행이 될것입니다.
// 요청이 들어옴 -> JwtFilter 통과함 -> OwnerCheckInterceptor
// 유효하면 UserController 접근 ->
// UserEmailUpdate -> 타켓 대상인 서비스 레이어의 메서드가 -> TimeCheckAop 실행 전 로직 수행
// UserEmailUpdate 실행이 끝남 -> TimeCheckAop 실행후 로직 수행
// Controller에서 return 값 넘겨줌
// JwtFilter 통과해서 Postman으로 결과 전달.
이 순서대로 체크를 좀 해볼까 합니다.
2026-01-27T16:45:05.668+09:00 INFO 32708 --- [advance]
[nio-8080-exec-1] c.e.advance.common.aspect.TimeCheckAop : [AOP] login 실행됨 in 739 ms
2026-01-27T16:45:48.421+09:00 INFO 32708 --- [advance]
[nio-8080-exec-2] c.e.advance.common.filter.JwtFilter : 1번째 : Jwtfiltet 인증/인가 성공 -> 다음 단계로 넘어감
2026-01-27T16:45:48.422+09:00 INFO 32708 --- [advance]
[nio-8080-exec-2] c.e.a.c.i.UserOwnerCheckInterceptor : currentUsername='장지혁' length=3
2026-01-27T16:45:48.422+09:00 INFO 32708 --- [advance]
[nio-8080-exec-2] c.e.a.c.i.UserOwnerCheckInterceptor : pathUsername='장지혁' length=3
2026-01-27T16:45:48.422+09:00 INFO 32708 --- [advance]
[nio-8080-exec-2] c.e.a.c.i.UserOwnerCheckInterceptor : 2번째 : interceptor controller 들어가기 전 마지막 권한 검사 실행
2026-01-27T16:45:48.436+09:00 INFO 32708 --- [advance]
[nio-8080-exec-2] c.e.a.user.Controller.UserController : 3번째 : interceptor를 통과후 Controller 로직 수행
2026-01-27T16:45:48.438+09:00 INFO 32708 --- [advance]
[nio-8080-exec-2] c.e.advance.common.aspect.TimeCheckAop : 4번째 : 서비스 레이어 메서드 실행 전 AOP 로직 수행
Hibernate: select u1_0.id,u1_0.email,u1_0.password,u1_0.role_enum,u1_0.username from users u1_0 where u1_0.username=?
2026-01-27T16:45:48.451+09:00 INFO 32708 --- [advance]
[nio-8080-exec-2] c.e.advance.user.service.UserService : 5번째 : 서비스 레이어 메서드 실행 완료
2026-01-27T16:45:48.451+09:00 INFO 32708 --- [advance]
[nio-8080-exec-2] c.e.advance.common.aspect.TimeCheckAop : 6번째 : 서비스 레이어 메서드 실행 후 AOP 로직 수행
2026-01-27T16:45:48.452+09:00 INFO 32708 --- [advance]
[nio-8080-exec-2] c.e.advance.common.aspect.TimeCheckAop : [AOP] updateUserEmail 실행됨 in 13 ms
Hibernate: update users set email=?,password=?,role_enum=?,username=? where id=?
2026-01-27T16:45:48.472+09:00 INFO 32708 --- [advance]
[nio-8080-exec-2] c.e.a.user.Controller.UserController : 7번째 : contoroller 수행 완료
2026-01-27T16:45:48.476+09:00 INFO 32708 --- [advance]
[nio-8080-exec-2] c.e.advance.common.filter.JwtFilter : 8번째 : JwtFilter 통과 완료 후 포스트맨 전달
제가 생각했던 흐름을 명확하고 올바르게 잘 흐르고 있다는 것을 확인 했습니다.
오늘은 AOP에 대해서 알게 됐습니다.
📅 날짜 : 2026-01-27
📌 주제 : Spring AOP 실행 시간 측정
✅ AOP가 필요한 이유
모든 서비스 메서드에 다음과 같은 로직을 반복 작성하는 것은
유지보수성과 확장성이 매우 떨어진다.
'심화 Spring > Interceptor & AOP' 카테고리의 다른 글
| Interceptor 구현 (0) | 2026.01.27 |
|---|---|
| Filter vs Intetceptor vs AOP (0) | 2026.01.26 |