Spring AOP - 적용 방식

목차

참고

본 포스트는 김영한의 스프링 핵심 원리 - 고급편 내용을 참고해 만들었습니다.

횡단 관심 사항

횡단 관심 사항(Cross-cutting Concern)은 애플리케이션 전반에서 공통적으로 사용되는 기능입니다. 즉, 여러 모듈에서 공통으로 사용되는 기능으로서, 여러 코드에 걸쳐 분산되어 있을 수 있습니다. 이러한 횡단 관심 사항은 핵심 비즈니스 로직과 분리되어 있기 때문에 애플리케이션의 유지 보수성과 확장성에 영향을 미칩니다.

횡단 관심 사항의 예로는 로깅, 보안, 트랜잭션 처리 등이 있습니다. 예를 들어, 여러 모듈에서 공통적으로 로그를 출력해야 한다면, 모든 코드에 로그를 출력하는 코드를 추가해야 합니다. 하지만 이러한 방식은 유지 보수성이 떨어지고 코드 중복이 발생합니다. 이를 해결하기 위해 로그 출력과 같은 공통 기능을 모듈화하고 재사용 가능한 코드로 만들어주는 것이 바로 AOP의 역할입니다.

AOP를 사용하면 핵심 로직 코드를 수정하지 않고도 횡단 관심 사항을 처리할 수 있습니다. 즉, 공통 기능을 모듈화하여 애플리케이션 전반에서 쉽게 사용할 수 있게 됩니다. 이를 통해 애플리케이션의 유지 보수성과 확장성이 향상되며, 코드의 가독성도 높아지는 등의 장점을 가집니다.

Spring AOP

AOP 를 사용하면 핵심기능부가기능 이 코드상 완전히 분리 된다.

스프링 AOP(Aspect-Oriented Programming)는 애플리케이션에서 공통적으로 사용되는 기능들을 모듈화하고, 재사용 가능한 코드로 만들어주는 모듈화 기능입니다. 이를 통해 애플리케이션에서 각각의 객체에서 반복되는 코드를 줄일 수 있으며, 객체 간의 결합도를 낮출 수 있습니다.

스프링 AOP는 프록시 기반의 AOP 방식을 사용합니다. 스프링에서는 AOP 구현을 위해 XML 기반 AOP 와 Annotation 기반 AOP 두 가지 방식을 제공합니다.

Spring AOP 구성 요소

Aspect, Advice, JoinPoint, Pointcut 으로 구성됩니다.

  • Aspect
    • 애플리케이션 전반에서 공통으로 사용되는 기능을 모듈화한 것입니다.
  • Advice
    • Aspect에서 구현한 기능을 말하며, 횡단 관심 사항을 구현한 구체적인 메소드입니다. Before, After, Around 등의 Advice 유형이 있습니다.
  • JoinPoint
    • Advice가 적용될 위치입니다. 메소드 호출, 필드 접근 등이 JoinPoint가 될 수 있습니다.
  • Pointcut
    • Join point의 집합으로, Advice가 적용될 Join point를 선택합니다.

AOP 적용 시점

AOP 는 적용 되는 시점따라 컴파일 시점, 클래스 로딩 시점, 런타임 시점 세가지로 나눌 수 있습니다.

1. 컴파일 시점에 AOP 적용 - 바이트 코드 조작

자바 소스를 자바 바이트 코드로 컴파일 하는 시점에 부가 기능 로직을 추가

첫번째는 컴파일 시 AOP 가 적용되는 시점입니다. 컴파일러가 소스 코드를 바이트 코드 로 변환할 때, AOP 코드를 함께 조합합니다. 이 방식은 코드가 컴파일 되는 시점에 AOP가 적용되기 때문에, 애플리케이션의 실행 시간에 성능 문제가 발생할 확률이 낮습니다. 하지만 AOP를 적용하기 위해서는 코드의 재컴파일이 필요하기 때문에, 런타임에 동적으로 로딩되는 클래스에 대해서는 적용할 수 없습니다.

컴파일 시점에 AOP 를 적용하기 위해서는 AspectJ에서 제공하는 특별한 컴파일러를 사용해야 합니다. 원본 로직에 부가기능 로직이 추가되는 것을 Weaving 이라고 한다.

2. 클래스 로딩 시점에 AOP 적용 - class 파일 조작

자바 바이트 코드를 JVM 내 메모리 영역에 올리기 전에 부가기능 로직을 추가한다.

두번째는 클래스를 로딩 시 AOP 코드를 적용하여 class 파일 생성시 조작 방식 입니다. 이 방식은 런타임에 동적으로 로딩되는 클래스에 대해서도 AOP를 적용할 수 있으며, 애플리케이션의 실행 시간에 성능 문제가 발생할 확률이 낮습니다. 하지만 클래스를 로딩하는 시점에서 AOP 코드가 적용되기 때문에, 애플리케이션의 시작 시간이 느려질 수 있습니다.

클래스 로딩시점에 AOP 를 적용하는 것을 로드 타임 위빙 이라고 한다. 자바를 실행할 때 특별한 옵션을 통해 클래스 로더 조작기를 지정해야 한다.

3. 런타임 시점에 AOP 적용

어플리케이션이 실행중일 때 부가기능 로직을 추가한다. Spring AOP에서는 기본적으로 런타임 시점에 AOP가 적용됩니다.

세번째 방식은 애플리케이션이 실행되는 시점에 AOP 코드를 적용하는 런타임 시 적용하는 방식입니다. 이 방식은 애플리케이션의 실행 중에도 AOP를 적용할 수 있으며, 컴파일 시점이나 로드 시점에 비해 자유도가 높습니다. 하지만 AOP 코드를 적용하는 과정에서 애플리케이션의 성능에 영향을 미칠 수 있습니다.

Spring AOP에서는 기본적으로 런타임 시 AOP 가 적용됩니다. 하지만 필요에 따라 컴파일 시점이나 로드 시점에서 AOP를 적용할 수 있도록 옵션을 제공합니다.

프록시 방식의 AOP 는 프록시를 통해야 부가기능을 사용할 수 있어 final, 생성자 와 같은 것에서는 AOP 기능을 적용하기 어려운 제한이 있습니다.

AOP 적용 위치

  • AOP 적용 가능 위치 (JoinPoint)
    • 생성자, 필드 값 접근, static 메서드 접근, 메서드 실행
    • AOP 를 적용할 수 있는 위치를 JoinPoint 라고 한다.
  • AspectJ 를 사용하면 컴파일 시점클래스 로딩 시점 에서 AOP 를 적용할 수 있다.
  • Spring AOP 는 프록시 방식을 사용해 AOP 를 적용하기 때문에 메서드 실행 시점 에만 AOP 를 적용할 수 있다.
    • 프록시는 메서드 오버라이딩 개명으로 작동한다.
    • 프록시를 사용하는 Spring AOPJoinPoint 는 메서드 실행으로 제한된다.
  • 스프링 컨에티너에서 관리하는 Bean 에만 Spring AOP 를 적용할 수 있다.
Share