스프링을 처음 공부하다 보면 AOP(Aspect Oriented Programming, 관점 지향 프로그래밍)이라는 내용이 나오는데요. 관점 지향 프로그래밍이니 Aspect Oriented Programming 이라는 어려운 용어를 들으면 어렵게 느껴지지만, 결국에는 흩어져 있는 공통 관심사를 한 곳에 모아서 관리하는 기법이라고 이해하시면 훨씬 편합니다. 이번 글에서는 스프링에서 AOP가 왜 필요하고, 어떻게 동작하는지 한 번 정리해보려고 합니다.
AOP란 무엇인가?

전통적인 객체지향 프로그래밍(OOP)에서는 보통 도메인 별로 클래스를 나누고, 각 클래스 안에 해당 도메인의 책임을 모아둡니다. 하지만 실제 서비스를 만들다 보면 다음과 같은 코드가 여러 레이어에 반복되는 경우가 많습니다.
- 요청/응답 로그 남기기
- 메서드 실행 시간 측정
- 트랜잭션 시작/커밋/롤백
- 권한 체크, 인증 처리
이러한 기능들은 비즈니스 로직(핵심 관심사)이 아니라 “공통 관심사(Cross-cutting Concern)”입니다. 서비스, 리포지토리, 컨트롤러 등 곳곳에 흩어져 버리면 코드가 지저분해지고, 수정도 어렵고, 실수로 빼먹기도 쉽습니다. AOP는 이런 공통 관심사를 한 곳에 모아서 선언적으로 적용할 수 있게 해주는 기법입니다. 즉, 비즈니스 로직은 비즈니스에만 집중하게 만들고, 로그/트랜잭션/보안 같은 부가 기능은 별도의 모듈(Aspect)로 분리해서 관리하는 거죠.
AOP 핵심 용어 정리

- Join Point : AOP를 적용할 수 있는 지점 (메서드 호출, 예외 발생 등)
- Pointcut : 실제로 AOP를 적용할 지점을 선택하는 표현식
- Advice : 언제, 무엇을 할지에 대한 실제 부가 기능 코드 (Before, After, Around 등)
- Aspect : Pointcut + Advice를 하나로 묶은 모듈 (관점)
- Weaving : 기존 코드에 Aspect를 적용해서 실행 흐름에 끼워 넣는 과정
간단하게 말하면, “어디(Pointcut)에, 언제(Advice 타입), 무엇을(Advice 내용) 끼워 넣을지” 정의한 것이 Aspect입니다.
스프링에서 AOP는 어떻게 동작할까?
스프링 AOP는 기본적으로 프록시 기반으로 동작합니다. 스프링이 실제 빈 대신 프록시 객체를 만들어 두고, 메서드가 호출될 때 이 프록시가 가로채서(Intercept) 미리 설정해둔 Advice를 앞뒤로 실행해 줍니다.
- 기본 설정에서는 메서드 호출 시점에만 AOP 적용 (메서드 단위)
- 런타임 프록시 방식으로 동작 (코드 재컴파일 필요 X)
- 인터페이스가 있으면 JDK 동적 프록시, 없으면 CGLIB 사용
이 덕분에 기존 비즈니스 코드에는 AOP 관련 코드가 거의 들어가지 않고, 설정과 어노테이션만으로 부가 기능을 깔끔하게 끼워 넣을 수 있습니다.
예제 : 메서드 실행 시간 로깅 Aspect
서비스 메서드가 얼마나 오래 걸리는지 실행 시간을 측정하는 공통 기능을 AOP로 분리해 보겠습니다.
@Aspect
@Component
public class TimeLoggingAspect {
// 컨트롤러, 서비스, 리포지토리 패키지 아래의 모든 메서드 대상
@Around("execution(* com.example..*(..))")
public Object logExecutionTime(ProceedingJoinPoint joinPoint) throws Throwable {
long start = System.currentTimeMillis();
try {
// 실제 대상 메서드 호출
return joinPoint.proceed();
} finally {
long end = System.currentTimeMillis();
long duration = end - start;
String methodName = joinPoint.getSignature().toShortString();
System.out.println("[ExecutionTime] " + methodName + " took " + duration + " ms");
}
}
}
이렇게 작성해 두면, 지정한 패키지 아래의 메서드가 호출될 때마다 비즈니스 코드 수정 없이 실행 시간이 자동으로 로그에 찍히게 됩니다.
Advice 종류 한 번에 정리
- @Before : 메서드 실행 직전에 수행
- @AfterReturning : 메서드가 정상 종료된 후에 수행
- @AfterThrowing : 예외가 던져졌을 때 수행
- @After : 정상/예외 상관없이 메서드 종료 후 항상 수행
- @Around : 메서드 호출 전후를 모두 감싸는 형태 (가장 강력)
실무에서는 @Around 하나로 시작해서 필요한 경우 @Before, @AfterReturning 등을 조합해서 사용하는 패턴이 많습니다.
AOP의 장점
- 관심사 분리 : 비즈니스 로직과 로그/트랜잭션/보안 같은 부가 기능을 분리할 수 있습니다.
- 코드 중복 제거 : 여러 클래스에 흩어져 있던 공통 코드를 한 곳에 모을 수 있습니다.
- 유지보수성 향상 : 공통 기능 수정 시 한 파일만 고치면 되기 때문에 변경 비용이 줄어듭니다.
- 가독성 향상 : 실제 서비스/도메인 코드는 본연의 역할에만 집중할 수 있습니다.
결국 AOP는 “핵심 로직은 더 단순하게, 공통 로직은 더 체계적으로” 관리하기 위한 도구라고 볼 수 있습니다.
'ETC. > Spring' 카테고리의 다른 글
| [Spring] 스프링 프레임워크 MVC 처리 프로세스 - DispatcherServlet (0) | 2025.11.17 |
|---|---|
| [Spring] 스프링 IoC(제어의 역전), DI(의존성 주입) 완벽 이해하기 (0) | 2025.11.15 |
| [Spring] 스프링 부트 게시판 만들기-4 계층형 댓글 만들기 (0) | 2021.01.05 |
| [Spring] 스프링 부트 게시판 만들기-3 글 상세보기 페이지 만들기 (0) | 2021.01.04 |