AOP 프록시 동작 원리

헨도·2025년 12월 3일

SpringBoot

목록 보기
40/41
post-thumbnail

AOP?

AOP는 '메서드 앞뒤로 특정 기능을 끼워 넣는 기술'

ex)

  • 메서드 실행 전 로그 찍기
  • 실행 후 걸린 시간 측정
  • 트랜잭션 시작 / 커밋
  • 권한 검사
  • 캐싱

이런 부가 기능을 자동으로 넣을 수 있게 해주는 것이 AOP

그럼 이걸 어떻게 넣을까?
-> 스프링이 '프록시 객체'를 만들어준다.


프록시? 그게 뭐야?

프록시는 '원래 객체를 대신해서 앞에 선 대리인 같은 존재'

ex)

[내 코드] → OrderService.order()
        ↓
[스프링 프록시] → (부가기능 : 로그/트랜잭션) → 실제 OrderService.order() 실행

내 코드는 OrderService를 호출한다고 생각하지만, 사실은 Proxy가 가로채서 부가기능을 실행한 후에 원본 실행


동작 순서

1. @Transactional 같은 AOP 어노테이션 확인
2. 원본 객체 대신 프록시 객체 생성
3. 메서드 호출을 프록시가 가로챔
4. 부가 기능 실행 후 실제 메서드 호출

1. @Transactional 같은 어노테이션 확인

스프링이 컴포넌트 스캔할 때 '이 클레스에는 AOP 어노테이션이 붙어있네?'라고 판단


2. 원본 객체 대신 프록시 객체 생성

스프링은 2가지 방식 중 하나로 프록시를 생성

  • JDK Dynamic Proxy → 인터페이스 기반
  • CGLIB Proxy → 클래스 상속 기반

그 결과 컨테이너에는 원본이 아니라 프록시가 등록됨

JDK Dynamic Proxy vs CGLIB Proxy

JDK Proxy = '인터페이스가 있으면 인터페이스를 흉내내어 프록시 생성'
CGLIB = '인터페이스가 없으면 클래스를 상속하여 프록시 생성'

  • JDK Dynamic Proxy - 인터페이스 기반 프록시
public interface PaymentService {
	void pay();
}
@Service
public class PaymentServiceImpl implements PaymentService {
	public void pay() { ... }
}
  • CGLIB Proxy - 클래스 상속 기반 프록시
@Service
public class OrderService {
	public void order() { ... }
}
public class OrderServiceProxy extends OrderService {
	@Override
    public void order() {
    	// 부가 기능
        super.order();
    }
}

요약

구분JDK Dynamic ProxyCGLIB Proxy
기반인터페이스클래스 상속
인터페이스 필요 조건있어야 한다없어도 된다
생성 방식인터페이스 구현 객체 생성원본 클래스를 상속한 서브클래스 생성
제한인터페이스 없으면 생성 Xfinal 클래스/메서드 못 감쌈
속도좀 더 가벼움상대적으로 무거움

3. 메서드 호출을 프록시가 가로챔

내 코드가 호출하는 대상은 이미 프록시

내 코드 -> Proxy.order() -> (AOP 기능 실행) -> 실제 order() 실행

4. 부가 기능 실행 후 실제 메서드 호출

ex) @Transactional

Proxy : 트랜잭션 시작
  ↓
원본 메서드 호출
  ↓
정상 종료 : 커밋
예외 발생 : 롤백
profile
Junior Backend Developer

0개의 댓글