ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • [Spring] 스프링 핵심 원리 - 스프링 AOP
    Study/Spring 2025. 4. 23. 21:45

    AOP 소개 - 핵심 기능과 부가 기능

    • 어플리케이션 로직은 크게 핵심 기능과 부가 기능으로 나눌 수 있음
      • 핵심 기능 : 해당 객체가 제공하는 고유의 기능
      • 부가 기능 : 핵심 기능을 보조하기 위해 제공되는 기능 ex) 로그 추적 로직, 트랜잭션 기능
        • 단독으로 사용되지 않고, 핵심 기능과 함께 사용됨
    • 부가 기능 적용 문제
      • 보통 부가 기능은 여러 클래스에 걸쳐서 함께 사용됨. 따라서 이러한 부가 기능은 횡단 관심사(cross-cutting concerns)가 됨
        • 즉, 하나의 부가 기능이 여러 곳에 동일하게 사용되다는 뜻
      • 아래와 같은 문제 발생
        • 부가 기능이 여러 곳에 퍼져 중복 코드를 만들어냄
        • 중복으로 인해 부가 기능을 변경하거나 부가 기능의 적용 대상을 변경할 때 많은 수정이 필요함

     

    AOP 소개 - Aspect

    • 위와 같은 부가 기능의 문제를 보완하기 위해 Aspect라는 개념을 도입
      • 부가 기능과 부가 기능을 어디에 적용할지 선택하는 기능을 합해서 하나의 모듈로 만듦
      • Aspect는 부가 기능과, 해당 부가 기능을 어디에 적용할지 정의한 것
      • 스프링이 제공하는 Advisor도 Advice(부가 기능)와 Pointcut(적용 대상)을 가지고 있어서 개념상 하나의 Aspect임
    • Aspect는 '관점'이라는 뜻으로, 이름 그대로 어플리케이션을 바라보는 관점을 하나하나의 기능에서 횡단 관심사(cross-cutting concerns) 관점으로 달리 보는 것
    • Aspect를 사용한 프로그래밍 방식을 '관점 지향 프로그래밍 AOP(Aspect-Oriented Programming)'이라 함
      • 횡단 관심사를 깔끔하게 처리하기 어려운 OOP의 부족한 부분을 보조하는 목적으로 개발됨
    • AOP의 대표적인 구현으로 AspectJ 프레임워크가 있음
      • 스프링도 AOP를 지원하지만 대부분 AspectJ의 문법을 차용하고, AspectJ가 제공하는 기능의 일부만 제공함

     

    AOP 적용 방식

    스프링런타임 시점에 프록시 방식의 AOP 를 사용

    • 런타임 시점컴파일과 클래스 로딩이 끝나서 이미 자바가 실행되고 난 다음을 말함
      • 즉, 자바의 메인(main) 메서드가 이미 실행된 후
    • 따라서 자바 언어가 제공하는 범위 안에서 부가 기능을 적용해야 함
      • 스프링과 같은 컨테이너의 도움을 받고, 프록시과 DI, Bean Post Processor 같은 기능들을 동원해야 함
    • 최종적으로 프록시를 통해 스프링 빈에 부가 기능을 적용할 수 있음
    • 참고)
      • 스프링은 AspectJ의 문법을 차용하고 프록시 방식의 AOP를 적용함. AspectJ를 직접 사용하는 것이 아님

     

    프록시 방식을 사용하는 스프링 AOP의 장단점

    • 장점
      • 특별한 컴파일러나, 자바를 실행할 때 복잡한 옵션과 클래스 로더 조작기를 설정하지 않아도 됨
      • 스프링만 있으면 얼마든지 AOP를 적용할 수 있음
    • 단점
      • AOP 기능에 일부 제약이 있음
        • 메서드 실행 지점에만 AOP를 적용할 수 있음
          • 프록시는 메서드 오버라이딩 개념으로 동작함. 따라서 생성자나 static 메서드, 필드 값 접근에는 프록시 개념이 적용될 수 없음
          • 즉, 스프링 AOP의 조인 포인트는 메서드 실행으로 제한됨
        • 스프링 컨테이너가 관리할 수 있는 스프링 빈에만 AOP를 적용할 수 있음
          • BeanPostProcessor를 사용해 프록시 객체를 스프링 빈으로 등록하기 때문
          • 대상 객체가 스프링 빈이 아니라면 프록시 객체를 런타임에 생성하지 않음

     

    정리하면,

    • 스프링이 제공하는 AOP는 프록시를 사용
    • (스프링 빈을 대상으로) 프록시를 통해 메서드를 실행하는 시점에만 AOP가 적용
    • 스프링 AOP는 별도의 추가 자바 설정 없이 스프링만 있으면 편리하게 AOP를 사용할 수 있음

     

    추가) 컴파일 시점, 클래스 로딩 시점의 AOP 적용 방식

    더보기

    컴파일 시점

    • .java 소스 코드를 컴파일러를 사용해 .class를 만드는 시점에 부가 기능 로직을 추가
    • AspectJ가 제공하는 특별한 컴파일러를 사용해야 함
    • 컴파일된 .class를 디컴파일 해보면 Aspect 관련 호출 코드가 들어가 있음
    • AspectJ 컴파일러는 Aspect를 확인해 해당 클래스가 적용 대상인지 먼저 확인하고, 적용 대상인 경우에 부가 기능 로직을 적용함
    • 이렇게 원본 로직에 부가 기능 로직이 추가되는 것을 '위빙(Weaving)'이라 함

     

    단점

    • 컴파일 시점에 부가 기능을 적용하려면 특별한 컴파일러도 필요하고 복잡함

     

    클래스 로딩 시점

    • 자바를 실행하기 위해 클래스 파일을 JVM의 런타임 데이터 영역에 로딩
    • 이때 중간에서 .class 파일을 조작한 다음 JVM에 올릴 수 있음
    • 자바 언어는 .class를 JVM에 로딩하기 전에 조작할 수 있는 기능을 제공함
    • 이 시점에 Aspect를 적용하는 것을 '로드 타임 위빙'이라 함

     

    단점

    • 자바를 실행할 때 특별한 옵션(java -javaagnet)을 통해 클래스 로더 조작기를 지정해야 하는데, 이 부분이 번거롭고 운영하기 어려움

     

    런타임 시점에 적용하는 AOP와의 차이

    • 부가 기능 적용 차이
      • 컴파일 시점, 클래스 로딩 시점에 적용하는 AOP
        • 실제 대상 코드에 Aspect를 통한 부가 기능 호출 코드가 포함됨
        • AspectJ를 직접 사용해야 함
      • 런타임 시점에 적용하는 AOP
        • 실제 대상 코드는 그대로 유지됨. 대신 프록시를 통해 부가 기능이 적용됨
        • 따라서 항상 프록시를 통해야 부가 기능을 사용할 수 있음
    • AOP 적용 위치
      • 컴파일 시점, 클래스 로딩 시점에 적용하는 AOP
        • AspectJ를 사용해 바이트코드를 실제 조작하기 때문에 모든 지점에 적용할 수 있음
          • 적용 가능 지점(join point) : 생성자, 필드 값, static 메서드, 메서드
      • 런타임 시점에 적용하는 AOP
        • 프록시 방식을 사용하기 때문에 메서드 실행 지점에만 적용할 수 있음 (메서드 오버라이딩 불가능한 static 메서드 제외)

     

    AOP 용어 정리

    더보기
    • Join Point
      • Advice가 적용될 수 있는 위치, 메서드 실행, 생성자 호출, 필드 값 접근, static 메서드 접근 같은 프로그램 실행 중 지점
      • 추상적인 개념으로, AOP를 적용할 수 있는 모든 지점을 의미함
      • 스프링 AOP는 프록시 방식을 사용하므로 Join Point는 항상 메서드 실행 지점으로 제한
    • Pointcut
      • Join Point 중에서 Advice가 적용될 위치를 선별함
      • 주로 AspectJ 표현식을 사용해 지정함
      • 프록시를 사용하는 스프링 AOP는 메서드 실행 지점만 Pointcut으로 선별 가능
    • Target
      • Advice를 받는 객체, Pointcut으로 결정됨
    • Advice
      • 부가 기능
      • Around, Before, After와 같은 다양한 종류의 Advice가 있음
    • Aspect
      • Advice + Pointcut을 모듈화한 것
      • @Aspect를 생각하면 됨
      • 여러 Advice와 Pointcut이 함께 존재함
    • Advisor
      • 하나의 Advice와 하나의 Pointcut으로 구성
      • 스프링 AOP에서만 사용되는 특별한 용어
    • Weaving
      • Pointcut으로 결정한 Target의 Join Point에 Advice를 적용하는 것
      • 핵심 기능 코드에 영향을 주지 않고 부가 기능을 추가할 수 있음
    • AOP 프록시
      • AOP 기능을 구현하기 위해 만든 프록시 객체
      • 스프링에서 AOP 프록시는 JDK 동적 프록시 또는 CGLIB 프록시

    댓글

Designed by Tistory.