[Spring] AOP

윤여송·2026년 2월 7일

Spring

목록 보기
1/12

AOP

스프링의 AOP(Aspect Oriented Programming, 관점 지향 프로그래밍)는 말 그대로 어떠한 기능을 관점에 따라 분리하여 설계하는 기술이다.

쉽게 설명하면, 핵심 비즈니스 로직(회원가입, 주문 등)과 그 핵심 로직을 돕는 공통 부가기능(로깅, 보안, 트랜잭션 등)을 분리하여 필요할 때만 끼워 넣는 것이라고 이해하면 된다.

1. 왜 AOP를 사용할까?

만약 모든 메서드의 실행 시간을 측정해야 한다는 요구사항이 생길경우(공통 관심 사항) AOP가 없다면 수백개의 메서드에 일일이 시작 시간과 종료 시간을 기록하는 코드를 직접 적어야 한다.

  • 문제점: 코드가 중복되고, 핵심 비즈니스 로직이 부가기능(시간 측정 등)에 묻혀 가독성, 유지보수성이 떨어진다.
  • AOP의 해결책: 시간 측정 로직을 한 곳에 정의해두고, 적용하고 싶은 위치(모든 서비스 메서드 or 회원가입 로직 등)를 지정하면 스프링이 알아서 해당 코드를 적용위치에서 실행해 준다.

2. AOP의 핵심 개념 5가지

Aspect: 흩어진 관심사(공통 기능)을 모듈화한 것
Target: Aspect를 적용하는 곳
Advice: 실질적으로 수행해야 하는 기능
JoinPoint: Advicer가 적용될 수 있는 지점
Pointcut: JoinPoint중에서 실제로 Advice를 적용할 위치

3. 스프링 AOP의 동작 원리(프록시)

스프링은 프록시(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");
        }
    }
}
  1. @Around: "언제" 실행할 것인가?
  • 대상 메서드의 실행 전과 후를 모두 제어할 수 있다. (joinPoint.proceed())
  • @Before: 메서드 실행전 - joinPoint.proceed() 호출전
  • @After: 성공/실패 여부 관계없이 마지막 - finally 블록
    안
  1. execution(...): "어디에" 적용할 것인가?(범위 설정)
@Around("execution(* hello.hello_spring.service..*(..))") // 모든 서비스
  1. 특정 메서드만 골라서 실행하고 싶다면?
  • 특정 클래스만: execution(* hello.hello_spring.service.MemberService.*(..))
    - (MemberService 클래스의 메서드만 적용)
  • 특정 메서드 이름만: execution(* hello.hello_spring.service..*get*(..))
    - (이름에 'get'이 들어가는 메서드만 적용)

결론적으로 AOP는 유지보수를 편하게 해주고 코드를 깔끔하게 만들어주는 강력한 도구이다.

profile
y_some__velog

0개의 댓글