AOP(관점 지향 프로그래밍), 쉽게 배우기
프로그래밍하다 보면 여러 메서드에 반복적으로 들어가는 코드가 많아요.
예를 들어
- 로그 남기기
- 실행 시간 측정
- 권한 체크
이런 건 진짜 자주 나오죠.
AOP(Aspect Oriented Programming)는
이런 “공통적으로 필요한 기능”만 따로 빼서, 코드 전체에 한 번에 적용할 수 있게 도와주는 기술이에요.
1. 스프링 AOP 기본 예시
1) Aspect 클래스 만들기
import org.aspectj.lang.annotation.*;
import org.aspectj.lang.JoinPoint;
import org.springframework.stereotype.Component;
@Aspect // AOP에서 관점(Aspect)임을 표시
@Component // 스프링 빈으로 등록
public class LoggingAspect {
// Pointcut: com.example.service 패키지 모든 메서드에 적용
@Pointcut("execution(* com.example.service..*(..))")
public void serviceMethods() {} // Advice: 메서드 실행 전에 로그를 남긴다
@Before("serviceMethods()")
public void logBefore(JoinPoint joinPoint) {
// 실행될 메서드 이름 출력
System.out.println("[AOP] 실행 전: " + joinPoint.getSignature().getName()); }
// Advice: 메서드 실행 후에 로그를 남긴다
@After("serviceMethods()")
public void logAfter(JoinPoint joinPoint) {
System.out.println("[AOP] 실행 후: " + joinPoint.getSignature().getName());
}
}
[코드 설명]
- @Aspect: 이 클래스가 AOP의 “관점”임을 선언
- @Pointcut: 적용 범위 지정 (여기선 서비스 계층의 모든 메서드)
- @Before, @After: 메서드 실행 전/후로 Advice(실제로 동작할 코드)를 지정
2) 실행 시간 측정 AOP 예시
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.springframework.stereotype.Component;
@Aspect
@Component
public class TimeCheckAspect {
// Around: 메서드 실행 전/후 전체를 감싸고 시간 측정
@Around("execution(* com.example.controller..*(..))")
public Object checkTime(ProceedingJoinPoint joinPoint) throws Throwable {
long start = System.currentTimeMillis(); // 시작 시간 기록
Object result = joinPoint.proceed(); // 실제 메서드 실행
long end = System.currentTimeMillis(); // 끝난 시간 기록
System.out.println("[AOP] " + joinPoint.getSignature().toShortString() +
" 실행 시간: " + (end - start) + "ms");
return result; // 원래 메서드의 결과를 그대로 반환
}
}
[코드 설명]
- @Around: 메서드 실행 전/후로 감싸서 동작 (가장 강력한 Advice)
- joinPoint.proceed(): 실제로 타깃 메서드가 실행됨
- 실행 시간 측정 및 출력
3) @AfterReturning으로 응답값 로깅
import org.aspectj.lang.annotation.AfterReturning;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.JoinPoint;
import org.springframework.stereotype.Component;
@Aspect
@Component
public class ResponseLoggingAspect {
// 컨트롤러 패키지의 모든 메서드 리턴값을 가로채서 로그 남김
@AfterReturning(pointcut = "execution(* com.example.controller..*(..))", returning = "response")
public void logResponse(JoinPoint joinPoint, Object response) {
System.out.println("[AOP] " + joinPoint.getSignature().toShortString() +
" 응답값: " + response);
}
}
[코드 설명]
- @AfterReturning: 메서드가 정상적으로 리턴한 후 동작
- returning = "response": 실제 리턴값을 받아서 사용할 수 있음
2. 실전에서 많이 쓰는 AOP 활용 예시
- 트랜잭션 관리: @Transactional 어노테이션이 내부적으로 AOP로 구현되어 있음
- 로깅: 예시처럼, 요청/응답, 실행 시간 등 남기기
- 보안: 권한 체크, 로그인 확인 등
3. 왜 AOP를 써야 할까?
- 반복되는 코드 제거: 핵심 로직에만 집중할 수 있음
- 유지보수 쉬움: 변경 시 한 곳만 수정하면 됨
- 관심사 분리: 비즈니스 코드와 공통 코드가 섞이지 않음
4. 참고자료 / 더 알아보기
'부트캠프' 카테고리의 다른 글
| 테이블 객체끼리 관계 만들기 (0) | 2025.06.24 |
|---|---|
| Spring Boot, H2, 그리고 JDBC (1) | 2025.06.23 |
| JPQL 정리 (3) | 2025.06.10 |
| StringBuilder (1) | 2025.05.14 |
| SQL 달리기반 문제 (0) | 2025.03.28 |