AOP - 1

Posted by sJun on November 13, 2020 ·

스프링에서 AOP는 OOP를 보완하기 위해서 나온 것이다.

객체 지향에서 모듈화의 핵심 단위는 클래스이고 AOP의 모듈화 단위는 Aspect 이다.

AOP가 어려운 이유는 난해한 용어 때문인 것 같다. 공식 문서에서도 AOP에 대한 용어가 별로 직관적이지 않다라고 나와있다.

Unfortunately, AOP terminology is not particularly intuitive.

출처 : spring.io


  • Aspect : 여러 클래스를 관통하는 관심사의 모듈화를 뜻하고 Java에서 트랜잭션 관리가 좋은 예이다.

    여러 객체에 공통으로 적용되는 기능

  • Join Point : AOP에서 조인 포인트는 항상 메서드 실행을 뜻한다.

    Advice를 적용가능한 시점

  • Advice : 특정 join point에서 aspect가 취한 Action

    Aspect를 ‘언제’ 핵심코드에 적용할 지를 정의

  • Pointcut : join point와 일치하는 서술어이고 advice는 pointcut 표현식과 연관되어 있으며 pointcut과 일치하는 모든 join point에서 실행된다.

    Joinpoint의 부분 집합이고, Advice가 적용되는 Joinpoint를 나타냄

  • Introduction : type을 대신해서 추가적인 메서드와 필드를 선언할 수 있다.

  • Target object : 하나 이상의 Aspect에서 advised 하는 object. advised object 라고도 불리며 스프링 AOP는 런타임 프록시를 사용함으로써 실행되기 때문에 이 object는 항상 proxy object이다.

  • AOP proxy : aspect를 구현하기 위해 AOP 프레임 워크에 의해 생성되는 객체. 스프링 프레임워크에서 프록시는 JDK 동적 프록시 또는 CGLIB 프록시다.

  • Weaving : 다른 Application 유형이나 객체와 Aspect를 연결하여 adviced object를 생성한다. 순수 Java AOP 프레임 워크와 마찬가지로 spring AOP는 런타임에 위빙을 생성한다.

    Advice를 핵심 코드에 적용하는 것


AOP에는 여러 유형의 Advice가 있다.

  • Before Advice : Join point 이전에 실행되지만 Join point로 진행되는 실행 흐름을 막을 수 있는 기능이 없는 Advice.

  • After returning advice : Join point가 완료 되고 난 후에 실행하라고 명령하는 advice. (메서드가 exception 쓰로잉을 던지지 않을 때)

  • After throwing advice : 메서드가 예외 발생을 일으킬 때 실행됨

  • After (finally) advice : join point가 예외를 발생시키나 안시키나 관계 없이 실행하는 advice

  • Around advice : 가장 광범위한 advice. Around advice는 메서드 호출 전후에 사용자가 지정한 동작을 수행할 수 있다.

스프링은 요구한 동작을 수행할 수 있는 ‘최소한의’ 강력한 Aspect를 쓰는 것을 추천한다.

예를 들어 메서드 리턴값으로 캐시만 업데이트하는 것이 필요하다면, around advice가 같은 일을 수행할 수 있지만 after returning advice를 구현하는 것이 더 좋다. 즉 가장 구체적인 advice 유형을 사용하면 오류 가능성이 더 적어지기 때문이다.

point cut과 일치하는 join point 의 개념은 AOP의 핵심이고, interception만 제공하는 이전 기술과는 다르다.

pointcut을 이용하면 advice가 객체 지향 계층과 독립적으로 타겟팅이 가능하다.

예시로, 명시적 트랜잭션 관리를 제공하는 around advice를 사용해서 여러 곳에 있는 메서드들에 대해 한번에 적용이 가능하다.

Spring AOP 기능 및 목표

스프링 AOP는 순수 Java코드로 구현되기 때문에 특별한 컴파일 과정이 필요하지 않다.

스프링 AOP는 현재 메서드가 실행 중인 join point만 지원한다. 필드 인터셉션은 지원하지 않지만 따로 추가 설정이 가능하다.

필드 접근을 advice하고 join point를 업데이트 해야하는 상황이라면 AspectJ라는 언어를 고려하는 것이 좋다.

스프링 AOP는 다른 AOP 프레임 워크와의 접근 방식은 다르다. 목표는 가장 완벽한 AOP 구현을 제공하는 것이 아니라 AOP 구현과 Spring IoC 간의 통합을 제공하여 애플리케이션들의 일반적인 문제를 해결하기 위한 것이다.

스프링 AOP는 기본적으로 AOP 프록시에 표준 JDK 동적 프록시를 적용한다. 이를 통해서 모든 인터페이스를 프록시 할 수 있다.

CGLIB를 사용할 수도 있는데 인터페이스가 아닌 프록시 ‘클래스’에 필요하다. 보통은 인터페이스를 이용해 프로그래밍하는 것이 좋은 방법이지만 인터페이스에서 선언되지 않은 메서드를 Advice해야하거나 프록시 된 객체를 구체적인 타입으로 메서드로 전달해야하는 경우 CGLIB을 강제적으로 사용하는 것이 가능하다.

가장 중요한 것은 Spring AOP가 프록시 기반이라는 것이다.