AOP란? - 관점 지향 프로그래밍

문준일·2025년 4월 1일

Java를 접해본 사람이라면 누구나 OOP, AOP에 대해서는 간략하게나마 들어본 경험이 있을 것이다. OOP는 익숙하지만 AOP에 대해서는 자세히 모르는 이유로 AOP에 다뤄보고자 한다.

1️⃣ AOP란?

AOP(Aspect-Oriented Programming)는 관점 지향 프로그래밍이라고도 하며, 공통적으로 사용되는 관심사를 핵심 로직과 분리해서 재사용성, 유지보수성을 높이기 위한 프로그래밍 패러다임이다.

좀 더 쉽게 말하면, 모든 클래스에서 공통적으로 수행해야 할 기능(예: 로깅, 보안, 트랜잭션 처리 등)을 따로 빼서 관리하는 방식이라고 보면 된다.

서비스에서 필요한 내용은 비즈니스 로직이라고 불리는 핵심 기능만 수행할 수 있으면 된다.
그 외에 시간을 잰다든지, 권한을 체크한다든지, 트랜잭션을 건다든지 하는 것은 모두 인프라 로직이다.
이 인프라 로직은 전 영역에서 나타나는 경우가 많기 떄문에 중복코드를 만들어 낼 가능성이 있고, 이런 문제로 유지보수에 어려움을 겪을 수 있다. 또한 비즈니스 로직과 섞여있으면 비즈니스 로직을 이해하기가 어렵다.

이렇게 인프라 로직은 로깅, 트랜잭션, 권한 검사 등 하나의 관심사를 갖게 된다. 비즈니스 로직을 수행하는데 있어 부가기능이 되는 인프라 로직의 중복이 횡단으로 나타나기 때문에 이걸을 횡단 관심사(cross-cutting concern)이라고 부른다.


2️⃣ AOP의 주요 개념

용어설명
Aspect공통 기능 (예: 로깅, 트랜잭션 등) ▶ 횡단 관심사!(Advice + PointCut)
Join PointAspect를 적용할 수 있는 지점 (예: 메서드 실행 시점)
Advice실제 실행되는 공통(부가) 기능 코드
PointcutAdvice를 적용할 Join Point를 선택하는 표현식 ▶ 어드바이스를 어디에 적용할지 결정
WeavingAspect와 핵심 로직을 엮는 과정 (컴파일, 로드, 런타임 중 하나)

3️⃣ 예시로 이해하는 AOP

💡 예시: 로그를 출력하는 기능

어떤 메서드가 실행될 때마다 실행 시간을 측정해서 로그로 남기고 싶다고 가정해보자.

public void createUser() {
    long start = System.currentTimeMillis(); // 로그 시작 시간

    // 핵심 비즈니스 로직
    userRepository.save(user);

    long end = System.currentTimeMillis(); // 로그 종료 시간
    System.out.println("실행 시간: " + (end - start));
}

이런 식의 코드를 모든 서비스 메서드에 반복해서 작성하는 것은 비효율적이며 유지보수성도 떨어진다. 이 문제를 해결해주는 것이 바로 AOP이다.


💡 예시: AOP 적용

AOP를 적용하면 아래와 같은 방식으로 공통 기능을 분리할 수 있다.

@Aspect // [Aspect] 이 클래스는 공통 관심사를 모아놓은 '관점(Aspect)'임을 나타냄
@Component // Spring Bean으로 등록되도록 설정
public class LoggingAspect {

    @Around("execution(* com.example.service.*.*(..))")
    // [Pointcut] service 패키지 하위의 모든 메서드에 적용하겠다는 설정
    // [Advice] @Around: 메서드 실행 전후로 로직을 실행하겠다는 의미

    public Object logExecutionTime(ProceedingJoinPoint joinPoint) throws Throwable {
        long start = System.currentTimeMillis(); // 메서드 실행 전

        Object result = joinPoint.proceed(); // [Join Point] 실제 대상 메서드 실행

        long end = System.currentTimeMillis(); // 메서드 실행 후
        System.out.println(joinPoint.getSignature() + " 실행 시간: " + (end - start));
        return result; // 원래 메서드의 반환값을 그대로 리턴
    }
}

이 코드에서의 AOP 구성 요소 요약

AOP 용어코드 예시설명
Aspect@Aspect가 선언된 클래스공통 기능(로깅)을 모아놓은 클래스
Advice@Around 메서드공통 기능을 실제로 수행하는 코드 블록
Join PointjoinPoint.proceed()대상이 되는 실제 메서드 실행 시점
Pointcut"execution(* com.example.service.*.*(..))"어떤 메서드에 적용할지 정의하는 표현식
WeavingSpring이 런타임에 수행Aspect를 실제 객체에 적용하는 과정 (Spring이 자동으로 처리해줌)

4️⃣ AOP vs OOP 차이점

구분OOP (객체 지향 프로그래밍)AOP (관점 지향 프로그래밍)
핵심 개념클래스와 객체를 통한 기능 분리공통 기능을 관점으로 분리
관심사 분리데이터/기능 단위로 분리횡단 관심사 분리 (공통 기능)
코드 중복공통 기능이 여러 클래스에 중복될 수 있음공통 기능을 Aspect로 분리 가능
예시UserService, ProductService 등LoggingAspect, TransactionAspect 등

→ OOP는 "무엇을 할지", AOP는 "언제 어떻게 할지" 에 집중한다고 볼 수 있다.


📌 정리

  • AOP는 공통적인 기능을 별도의 모듈로 분리해 코드의 중복을 줄이고 유지보수성을 높이는 데 도움을 준다.
  • Spring Framework에서는 AOP를 매우 손쉽게 사용할 수 있는 구조가 마련되어 있다.
  • OOP와 함께 사용하면 훨씬 강력하고 깔끔한 코드를 구성할 수 있다.

    AOP는 복잡성 증가와 디버깅 어려움 등의 어려움이 있으니 특정한 횡단 관심사를 관리해야하는 경우에 선택적으로 사용하자!

profile
하나씩 실천하는 개발자

0개의 댓글