AOP(Aspect-Oriented Programming)

Aspect-Oriented Programming은 관점 지향 프로그래밍을 의미합니다. 소프트웨어 개발에서 횡단 관심사(Cross-Cutting Concerns)를 분리하여 모듈화 하는 것인데요. 이는 객체 지향 프로그래밍의 단점을 보완하는 프로그래밍 기법입니다.

Cross-Cutting Concerns(횡단 관심사)

횡단 관심사(Cross-Cutting Concerns)라는 개념이 익숙하진 않으실텐데요. 다음 그림을 통해 살펴 보겠습니다.

Cross-cutting concerns

OOP(Object-Oriented Programming, 객체 지향 프로그래밍)로 프로그래밍을 했다면, 그림에 나와있는 각 모듈처럼 기능 단위의 수직적 분리가 이루어졌을겁니다. 이에 AOP의 접근 방식을 더한다면, 그림처럼 공통적으로 사용되는 기능(로깅, 보안 등)을 클래스로부터 분리하여 모듈화를 시도하는 것이죠.

따라서 그림처럼 OOP의 접근 방식을 따라 객체 간 책임을 분리하여 클래스를 설계했다면, AOP의 접근 방식은 시스템 전체에 퍼져 있는 공통 관심사를 수평적으로 분리하여 OOP 코드의 단순화와 역할 분리를 돕습니다. 따라서 개념의 네이밍도 Cross-Cutting Concerns. 즉, 횡단 관심사라고 불리웁니다.

이러한 관심사를 코드의 주요 로직과 분리하면

  • 코드 중복제거
  • 가독성 향상
  • 유지보수 용이성

같은 이점을 얻을 수 있겠죠.

Aspect

Aspect는 직역하면 ‘관점’입니다. 위에서 말한 횡단 관심사(Cross-Cutting Concerns)를 정의하고 구현한 모듈을 말하는데요. 아래처럼 어노테이션을 통해 선언적으로 사용할 수 있습니다.

@Aspect
@Component
public class LoggingAspect {
  ...
}

Join Point

Join Point는 프로그램 실해중 Aspect를 적용할 수 있는 지점을 의미합니다. 주로 메서드 호출, 객체 생성, 예외 처리 등의 시점에서 발생하는데요. Spring AOP에서는 메서드 실행 시점만 Join Point로 지원합니다.

Advice

Advice는 Join Point에서 수행할 작업을 정의(Join Point에서 실행되는 코드 블록)합니다. 선언적으로 실행 타이밍을 지정해줄 수 있는데요.

  • @Before : 메서드 실행 전에 실행
  • @After : 메서드 실행 후에 실행
  • @AfterReturning : 메서드가 정상적으로 종료된 후 실행.
  • @AfterThrowing : 메서드에서 예외가 발생한 경우 실행.
  • @Around : 메서드 실행 전후에 실행, 가장 유연한 Advice

Pointcut

Pointcut은 Aspect를 적용할 Join Point를 지정하는데 사용하는데요. 특정 메서드나 클래스 그리고 패키지 등에 대해 실행 조건 정의를 선언적으로 사용할 수 있습니다.

@Sl4j
@Aspect
@Component
public class LoggingAspect {

    // Pointcut 정의
    @Pointcut("execution(* com.example.service.*.*(..))")
    public void serviceMethods() {}

    // Advice 정의
    @Before("serviceMethods()")
    public void logBeforeMethod(JoinPoint joinPoint) {
        log.info("메소드 실행: " + joinPoint.getSignature().getName());
    }
}

Weaving

Weaving은 Aspect와 애플리케이션의 실제 코드를 결합하는 과정을 말합니다. 다음과 같이 세가지 과정으로 나누는데요.

  • Compile time Weaving : 컴파일 시점에 적용(AspectJ에서 지원)
  • Load time Weaving : 클래스가 JVM에 로드될 때 적용(AspectJ에서 지원)
  • Runtime Weaving : 실행 시점에 적용(Spring AOP에서 사용)

정리

  1. Join Point : 애플리케이션의 특정 실행 지점
  2. Pointcut : Join Point 중에서 Aspect를 적용할 지점
  3. Advice : Pointcut으로 선택된 Join Point에서 실행할 구체적인 동작
  4. Weaving : 애플리에키션 코드에 적용하는 과정
  5. Aspect : 위 모든것을 하나로 묶은 모듈

AOP의 주요 활용 사례

  1. 로깅(Logging)
  2. 트랜잭션(@Transactional 어노테이션은 AOP로 구현 되어있음)
  3. 인증 및 권한 관리 : 사용자의 인증 상태와 권한을 확인하는 코드를 모든 컨트롤러에 작성하는 대신, AOP를 통해 특정 요청에만 적용하는 방법을 생각해볼 수 있습니다.
  4. 캐싱(Caching) : 자주 호출되는 메서드 결과를 캐싱 코드로 작성하여 성능을개선할 수 있습니다. Spring Cache같은 캐시 라이브러리도 AOP를 활용합니다.
  5. 모니터링 및 성능 추척 : 애플리케이션의 성능을 추적하거나 SLA(Service Level Agreement)를 준수하기 위해 특정 메서드의 실행 시간을 측정합니다.

AOP의 장단점

AOP는 횡단 관심사를 분리하여 코드의 품질과 유지보수성을 높일 수 있습니다. 그러나 모든 상황에 적합한 솔루션은 아니기에 장단점을 명확히 이해해야 하는데요.

장점

  • 공통 관심사를 중앙에서 관리하여 코드 중복을 최소화합니다.
  • 런타임에 새로운 기능을 손쉽게 추가할 수 있습니다.
  • 애플리케이션의 다양한 모듈에서 공통 관심사를 모듈화하여 캡슐화된 코드 작성이 가능합니다.

단점

  • Aspect가 런타임에 적용되므로 코드 실행 흐름을 추적하기 어려울 수 있습니다.
  • 오용, 과용시 코드의 복잡도가 증가합니다.
  • Aspect는 적용된 코드의 런타임 처리 때문에 약간의 성능 오버헤드가 발생합니다.
  • Spring AOP는 메서드 실행 Join Point만 지원하므로, 더 세부적인 제어가 필요할 경우 AspectJ를 사용해야합니다.

도입 여부를 판단하는 기준

  • 로깅이나 보안 등 반복적인 작업이 많다면 AOP로 횡단 관심사로 분리하는게 좋습니다. 단순한 작업만처리 한다면, AOP를 도입하지 않아도 됩니다.
  • 대규모 어플리케이션일 경우엔 AOP도입이 효과적이지만, 소규모 프로젝트에서는 과도한 설계가 될 수 있습니다.
  • 성능 오버헤드에 민감한 환경(실시간 처리 시스템)에서는 AOP 사용에 신중해야 합니다.

AOP가 기술면접에서 자주 언급되는 이유?

AOP(Aspect-Oriented Programming)은 OOP와 함께 면접 단골 질문입니다. AOP가 단순히 기술 구현에 그치지 않고 코드를 모듈화하고 유지보수성을 향상 시키는 중요한 개발 원칙중 하나이기 때문인데요.

  • “AOP를 도입했을 때 얻을 수 있는 장점은 무엇인가요?”
  • “AOP를 사용하지 않고 횡단 관심사를 구현하려면 어떤 방식이 필요할까요?”
  • “AOP 없이 트랜잭션 관리 로직을 모든 서비스에 구현하면 발생할 문제는 무엇인가요?”
  • “AOP를 사용하면 성능 문제가 발생할 가능성이 있는데, 이를 어떻게 해결하겠습니까?”

위 질문들은 AOP의 핵심 원칙과 실무 적용 방식을 이해했는지를 평가하기 위한 것으로, 면접관이 지원자의 문제 해결 능력과 소프트웨어 설계 철학을 파악하려는 의도에서 자주 나온다고 생각하는데요. 결론적으로, AOP는 기술 스택, 소프트웨어 설계 원칙을 동시에 지니고 있습니다. 따라서, AOP의 개념을 정확히 이해하고 활용 사례를 준비한다면 면접 준비에 많은 도움이 될 것 같습니다.