웹 서비스를 개발하다 보면 비즈니스 로직(회원가입, 주문 등) 외에
공통적으로 반복되는 코드들을 마주하게 됩니다.
이를 효율적으로 관리하기 위한
AOP(Aspect Oriented Programming)에 대해 알아보고자 합니다.
비즈니스 로직 사이사이에 들어가는 로깅, 트랜잭션, 보안 등은 모든 메서드에 중복되어 나타납니다. 이를 횡단 관심사(Cross-cutting Concerns)라고 부릅니다.
주방장이 요리(비즈니스 로직)를 하는데, 부수적인 일을 직접 다 해야 합니다.
문제점: 주방장이 요리에 집중하지 못해 핵심 로직보다 부가 코드가 많아지는
'코드 비대화'가 발생합니다.
주방장은 오직 '요리'에만 집중하고, 나머지는 주방 시스템(AOP)이 처리합니다.
가장 대표적인 사례입니다.
DB 작업 중 오류 발생 시 전체를 취소해야 하는데,
모든 메서드에 try-catch와 rollback 코드를 넣는 것은 매우 비효율적입니다.
@Transactional 어노테이션을 붙이면, 프록시 패턴을 이용해 AOP가 로직 전후로 트랜잭션 처리를 자동화합니다.어떤 API가 느린지 파악하기 위해 모든 메서드에 시간 측정 코드를 넣는 것은 유지보수에 치명적입니다.
@Around 어드바이스를 사용해 특정 패키지나 커스텀 어노테이션이 붙은 메서드의 실행 시간을 일괄 계산하여 로그를 남깁니다.특정 기능에 접근할 때마다 권한 등급을 검사하는 로직이 중복될 수 있습니다.
@CheckAdmin)을 만들고,| 용어 | 설명 |
|---|---|
| Aspect | 흩어진 공통 로직을 하나로 모듈화한 것 |
| Target | Aspect를 적용할 대상 (클래스, 메서드 등) |
| Advice | 실질적으로 수행할 코드와 실행 시점(언제) 정의 |
| Join Point | Advice가 적용될 수 있는 모든 지점 (Spring에서는 메서드 실행 시점) |
| Pointcut | Join Point 중 실제로 Advice를 적용할 상세 범위 선정 |
Proxy 기반: Spring AOP는 기본적으로 프록시(Proxy) 메커니즘을 사용합니다.
대상 객체를 직접 호출하는 것이 아니라,
중간에 프록시 객체를 두어 부가 기능을 실행합니다.
Self-Invocation 주의: 클래스 내부에서 내부 메서드를 호출할 때는
AOP가 적용되지 않는 '자기 호출' 문제를 유의해야 합니다.
(프록시 객체를 거치지 않고 내부에서 직접 메서드를 호출하면
AOP(부가 기능)가 동작하지 않습니다.
(출처: Spring Framework Documentation)