[Spring] AOP 동작 원리

AOP란?

AOP(Aspect Oriented Programming)란 관점 지향 프로그래밍으로 코드의 부가적인 관심사를 핵심 비즈니스 로직과 분리해서 관리하는 프로그래밍 기법입니다.

 

AOP의 목적

소스 코드 상에서 클래스마다 계속 반복되는 부분을 흩어진 관심사라고 부릅니다. 이런 흩어진 관심사를 Aspect로 모듈화하고 핵심 비즈니스 로직에서 분리하여 재사용 하는 것이 AOP의 목적입니다.

  • 핵심 로직에 집중하고,
  • 로깅, 트랜잭션, 예외 처리, 보안 같은 반복적인 부가 기능을 Aspect로 따로 빼서 관리

AOP가 없으면?

모든 서비스에 공통 기능이 중복됩니다.

public void placeOrder() {
	log.info("주문 시작"); // 모든 서비스마다 들어가야함
    try {
    	// 핵심 비즈니스 로직
    } finally {
    	log.info("주문 완료");
    }
}

 

결국 유지보수가 힘들고, 변경 시 전체 코드에 영향을 줍니다.

따라서, 공통 처리 로직을 한 군데에 몰아서 관리하고 필요할 때마다 자동으로 해당 메서드 앞뒤에 끼워주는 기술(AOP)이 등장하게 되었습니다.


AOP가 있으면?

공통 작업은 한 곳에 모아두고, 메서드 실행 전 후에 자동으로 끼워넣을 수 있습니다.

// 이 핵심 비즈니스 로직 앞 뒤로 공통 처리(Aspect)를 붙이고 싶음
public void sendMessage() {
	// 핵심 비즈니스 로직
}
  • 로깅
  • 트랜잭션
  • 보안
  • 예외처리
  • 비동기

해당 적업 모두 Aspect로 모듈화 가능합니다.


스프링 AOP 특징

항목 설명
프록시 기반 실제 객체를 감싼 프록시가 공통 기능을 삽입
스프링 빈만 적용 가능 스프링이 관리하는 빈이어야 AOP 동작
프록시를 거쳐야 Advice 적용 프록시를 우회하면 AOP 기능은 무시

트랜잭션이 작동하는 방식

@Transactional
public void placeOrder() {
	// 핵심 비즈니스 로직
}

 

해당 메서드가 실제 실행되면 아래와 같이 수행됩니다.

Controller -> OrderService(Proxy)
                - @Transactional: 트랜잭션 시작
                - 실제 placeOrder 실행
                - 성공 시 커밋 / 실패 시 롤백

프록시 객체란?

스프링이 @Service, @Component 등으로 등록한 클래스에 AOP 적용이 필요하면, 그 클래스 자체를 Bean으로 등록하지 않고 프록시 객체로 감싸서 등록합니다.

@Autowired
private OrderService orderService;

실제로는

OrderService$$EnhancerBySpringCGLIB...

처럼 프록시 객체가 주입됩니다.

 


프록시 동작

이 프록시 객체는 아래와 같이 원래 객체의 메서드를 감싸서 실행 제어를 추가합니다.

public class OrderServiceProxy extends OrderService {
    
    @Override
    public void placeOrder() {
        // 트랜잭션 시작
        try {
            super.placeOrder();
            // 트랜잭션 커밋
        } catch (Exception e) {
            // 롤백
            throw e;
        }
    }
}

내부 호출

public class OrderService {

    @Transactional
    public void methodA() {
        methodB(); // 프록시 우회 → 트랜잭션 안 먹힘
    }

    @Transactional
    public void methodB() {
        ...
    }
}
  • this.methodB() 는 프록시를 거치지 않음
  • AOP 적용(@Async, @Transactional 등)이 무시됨

해결책

방식 설명
외부 Bean에서 호출 AOP에 적용된 메서드를 다른 클래스로 분리
자기 자신 주입 자기 자신을 주입해서 호출 (코드 품질, 유지보수 이슈로 비권장)

 

'Spring' 카테고리의 다른 글

[Spring] - 공통 예외 처리 적용하기(2)  (0) 2025.04.06
[Spring] - 공통 예외 처리 적용하기(1)  (0) 2025.04.05