스프링의 AOP(Aspect Oriented Programming, 관점 지향 프로그래밍)는 말 그대로 어떠한 기능을 관점에 따라 분리하여 설계하는 기술이다.
쉽게 설명하면, 핵심 비즈니스 로직(회원가입, 주문 등)과 그 핵심 로직을 돕는 공통 부가기능(로깅, 보안, 트랜잭션 등)을 분리하여 필요할 때만 끼워 넣는 것이라고 이해하면 된다.
만약 모든 메서드의 실행 시간을 측정해야 한다는 요구사항이 생길경우(공통 관심 사항) AOP가 없다면 수백개의 메서드에 일일이 시작 시간과 종료 시간을 기록하는 코드를 직접 적어야 한다.
Aspect: 흩어진 관심사(공통 기능)을 모듈화한 것
Target: Aspect를 적용하는 곳
Advice: 실질적으로 수행해야 하는 기능
JoinPoint: Advicer가 적용될 수 있는 지점
Pointcut: JoinPoint중에서 실제로 Advice를 적용할 위치
스프링은 프록시(Proxy)라는 가짜 객체를 만들어 AOP를 구현한다.
1. 스프링 빈으로 등록된 객체를 호출할 때, 진짜 객체가 아닌 프록시 객체를 먼저 호출한다. (원본 객체를 손대지 않고 기능을 추가하기 위함)
2. 프록시 객체에서 공통 로직(Advice)을 실행한다.
3. 그다음 진짜 객체의 메서드를 호출하여 비즈니스 로직을 처리한다.

@Aspect
@Component
public class TimeTraceAop {
@Around("execution(* hello.hello_spring.service..*(..))") // 적용 범위 설정
public Object execute(ProceedingJoinPoint joinPoint) throws Throwable {
long start = System.currentTimeMillis();
try {
return joinPoint.proceed(); // 실제 핵심 로직 실행
} finally {
long finish = System.currentTimeMillis();
long timeMs = finish - start;
System.out.println("END: " + joinPoint.toString() + " " + timeMs + "ms");
}
}
}
@Around: "언제" 실행할 것인가?joinPoint.proceed() 호출전finally 블록execution(...): "어디에" 적용할 것인가?(범위 설정)@Around("execution(* hello.hello_spring.service..*(..))") // 모든 서비스
execution(* hello.hello_spring.service.MemberService.*(..))execution(* hello.hello_spring.service..*get*(..))결론적으로 AOP는 유지보수를 편하게 해주고 코드를 깔끔하게 만들어주는 강력한 도구이다.