본문 바로가기
개발

Spring AOP 개념 정리 – 로그 출력과 트랜잭션 처리에 왜 필요한가?

by suwimi 2025. 4. 21.

스프링 프레임워크(Spring Framework)를 활용하다 보면 반복적인 코드에 지치게 되는 순간이 있습니다. 예를 들어, 모든 서비스 메소드에 로그를 출력하거나, 트랜잭션을 걸어야 할 때 말이죠. 이럴 때 스프링 AOP(Spring AOP)를 활용하면 핵심 로직은 그대로 유지하면서 **공통 관심사(Cross-Cutting Concern)**를 깔끔하게 관리할 수 있습니다.

이번 글에서는 Spring AOP의 개념과 실제 적용 예제를 중심으로 쉽게 정리해보겠습니다.

 

Spring AOP란 무엇인가?

AOP는 Aspect Oriented Programming(관점 지향 프로그래밍)의 약자입니다.
기존 객체지향 프로그래밍은 로직 단위로 코드를 나누지만, AOP는 ‘관심사’ 중심으로 로직을 분리합니다.

예를 들어, 아래와 같은 작업은 모든 비즈니스 로직에 공통적으로 들어갈 수 있습니다.

  • 로그 출력
  • 실행 시간 측정
  • 인증/인가 체크
  • 예외 처리
  • 트랜잭션 처리

이러한 기능들을 각 메소드마다 일일이 넣으면 코드가 지저분해지고 유지보수도 어렵습니다.
그래서 스프링은 AOP 기능을 통해 이런 부가 기능을 별도의 코드로 관리할 수 있게 도와줍니다.

 

스프링 AOP는 어떻게 동작하는가?

Spring AOP는 프록시(Proxy) 기반으로 동작합니다. 즉, 실제 객체를 감싸는 프록시 객체가 존재하고, 해당 프록시가 메소드 호출을 가로채서 원하는 기능을 추가합니다.

예를 들어, 우리가 만든 MemberService 클래스에 메소드가 있을 때

public class MemberService {
    public void join(Member member) {
        // 핵심 로직
    }
}

이 메소드가 실행될 때 실제 메소드가 실행되기 전/후에 프록시 객체가 부가 작업을 수행하게 됩니다. 즉, 로그 출력이나 트랜잭션 시작/종료 같은 처리를 자동으로 끼워넣을 수 있는 것이죠.

 

 

AOP 핵심 용어 정리

스프링 AOP를 이해하기 위해서는 몇 가지 용어를 알고 있어야 합니다.

Aspect

공통 기능을 담고 있는 클래스입니다. 예: 로그 출력 클래스

Advice

실제로 수행할 부가 기능입니다. 예: 메소드 실행 전 로그 찍기

Join Point

Advice가 적용될 수 있는 지점입니다. 일반적으로 메소드 실행 시점을 뜻합니다.

Pointcut

Advice를 어떤 메소드에 적용할지 정의합니다. 예: com.example.service.*의 모든 메소드

Weaving

Advice를 실제 코드에 적용하는 과정입니다.

 

Spring AOP 예제 – 로그 출력 적용하기

스프링에서 AOP를 적용하려면 @Aspect 애노테이션과 함께 @Around, @Before, @After 등을 활용하면 됩니다. 아래는 서비스 메소드의 실행 시간을 측정하는 예제입니다.

@Aspect
@Component
public class LoggingAspect {

    @Around("execution(* com.example.service.*.*(..))")
    public Object logExecutionTime(ProceedingJoinPoint joinPoint) throws Throwable {
        long start = System.currentTimeMillis();

        Object result = joinPoint.proceed(); // 실제 메소드 실행

        long end = System.currentTimeMillis();
        System.out.println(joinPoint.getSignature() + " 실행 시간: " + (end - start) + "ms");

        return result;
    }
}

이 코드를 추가하면 com.example.service 패키지 아래의 모든 메소드가 실행될 때마다 실행 시간이 자동으로 출력됩니다.

 

 

스프링에서 트랜잭션 처리도 AOP다

많은 분들이 모르고 지나가는 부분인데, @Transactional도 사실 Spring AOP의 일종입니다.

@Transactional
public void saveUser(User user) {
    userRepository.save(user);
}

이 메소드는 내부적으로 프록시가 감싸고 있어 다음과 같은 흐름이 적용됩니다:

  • 트랜잭션 시작
  • 실제 메소드 실행
  • 성공 시 commit, 예외 시 rollback

우리가 직접 트랜잭션을 시작하고 종료하는 코드를 작성하지 않아도 되는 이유는 바로 Spring AOP가 대신 처리해주기 때문입니다.

 

AOP는 언제 활용하면 좋을까?

  • 모든 컨트롤러의 요청 로그를 남기고 싶을 때
  • 예외 발생 시 공통 알림 로직을 적용하고 싶을 때
  • 트랜잭션 범위를 설정하고 싶을 때
  • 성능 측정을 자동화하고 싶을 때

핵심 비즈니스 로직과 무관한 기능을 공통적으로 처리해야 할 때 AOP는 매우 유용합니다.

 

 

Spring AOP는 복잡한 기능처럼 보이지만, 실은 핵심 로직을 깔끔하게 유지하면서도 공통 기능을 효과적으로 적용할 수 있는 매우 실용적인 도구입니다.

특히 로그 출력, 트랜잭션 처리, 예외 처리처럼 모든 애플리케이션에서 반복되는 작업을 깔끔하게 처리해준다는 점에서 개발 생산성을 크게 높여줍니다.

앞으로 스프링 프로젝트에서 반복되는 로직을 발견한다면, AOP를 한번 떠올려보시길 바랍니다. 코드는 더 간결해지고, 유지보수는 더 쉬워질 것입니다.