몇 가지 핵심 AOP 개념과 용어를 정의하는 것부터 시작하겠습니다. 이 용어는 Spring에만 국한되지 않습니다. 불행하게도 AOP 용어는 특별히 직관적이지 않습니다. 그러나 Spring이 자체 용어를 사용한다면 훨씬 더 혼란스러울 것입니다.
측면(Aspect): 여러 클래스에 걸쳐 적용되는(cut across) 관심사의 모듈화입니다. 트랜잭션 관리는 엔터프라이즈 Java 애플리케이션의 크로스커팅(crosscutting) 문제에 대한 좋은 예입니다. Spring AOP에서 측면(ascpect)은 일반(regular) 클래스(스키마 기반 접근 방식) 또는 @Aspect
어노테이션이 달린 일반 클래스(@AspectJ 스타일
)를 사용하여 구현됩니다.
조인 포인트(Join Point): 메소드 실행이나 예외 처리 등 프로그램 실행 중 지점. Spring AOP에서 조인 포인트는 항상 메소드 실행을 나타냅니다.
어드바이스(Advice): 특정 조인 포인트에서 측면(aspect)이 취하는 조치(action). 다양한 타입의 어드바이스에는 "around", "before" 및 "after" 어드바이스가 포함됩니다. (어드바이스 타입은 나중에 논의됩니다.) Spring을 포함한 많은 AOP 프레임워크는 어드바이스을 인터셉터로 모델링하고 조인 포인트 주위에 인터셉터 체인을 유지합니다.
포인트컷(Pointcut) : 조인 포인트와 매칭되는 조건자(predicate)입니다. 어드바이스는 포인트컷 표현식과 연관되어 있으며 포인트컷과 매치되는 조인 포인트(예: 특정 이름을 가진 메소드 실행)에서 실행됩니다. 포인트컷 표현과 일치하는 조인 포인트 개념은 AOP의 핵심이며 Spring은 기본적으로 AspectJ 포인트컷 표현 언어를 사용합니다.
소개(Introduction): 타입을 대신하여 추가 메소드 또는 필드 선언. Spring AOP를 사용하면 어드바이스된 객체에 새로운 인터페이스(및 해당 구현)를 도입(introduce)할 수 있습니다. 예를 들어 소개(introduction)를 사용하여 Bean이 IsModified
인터페이스를 구현하도록 하고 캐싱을 단순화할 수 있습니다. (AspectJ 커뮤니티에서는 소개(introduction)를 타입 간 선언(inter-type declaration)이라고 합니다.)
대상 객체(Target object): 하나 이상의 측면(aspect)에서 어드바이스되는 객체입니다. "advised object"라고도 합니다. Spring AOP는 런타임 프록시를 사용하여 구현되므로, 이 객체는 항상 프록시 객체입니다.
AOP 프록시: 측면(aspect) 계약(contract)(advice 메소드 실행 등)을 구현하기 위해 AOP 프레임워크에서 생성된 객체입니다. Spring Framework에서 AOP 프록시는 JDK 동적 프록시 또는 CGLIB 프록시입니다.
위빙(Weaving): 측면(aspect)을 다른 애플리케이션 타입 또는 객체와 연결(link)하여 어드바이스된 객체를 생성합니다. 이는 컴파일 타임(예: AspectJ 컴파일러 사용), 로드(load) 타임 또는 런타임에 수행될 수 있습니다. 다른 순수 Java AOP 프레임워크와 마찬가지로, Spring AOP는 런타임에 위빙을 수행합니다.
Spring AOP에는 다음 타입의 어드바이스가 포함됩니다.
Before advice: 조인 포인트 이전에 실행되지만 실행 흐름이 조인 포인트로 진행되는 것을 방지할 수 있는 기능이 없는 어드바이스입니다(예외가 발생하지 않는 한).
After returning advice: 조인포인트가 정상적으로 완료된 후 실행하라는 어드바이스(예: 예외를 발생시키지 않고 메서드가 반환되는 경우)
After throwing advice: 예외를 발생시켜 메서드가 종료되면 실행하도록 어드바이스합니다.
After (finally) advice: 조인 포인트가 종료되는 수단(정상 또는 예외 반환)에 관계없이 실행되는 어드바이스입니다.
Around advice: 메소드 호출과 같이 조인 포인트를 둘러싸는 어드바이스입니다. 이것은 가장 강력한 어드바이스입니다. Around advice는 메소드 호출 전후에 사용자 정의 동작을 수행할 수 있습니다. 또한 조인 포인트로 진행할지, 아니면 자체 반환 값을 반환하거나 예외를 발생시켜, 어드바이스된 메서드 실행을 단축할지(shortcut) 선택하는 일도 담당합니다.
어라운드 어드바이스는 가장 일반적인 종류의 어드바이스입니다. AspectJ와 같은 Spring AOP는 전체 범위의 어드바이스 타입을 제공하므로 필요한 동작을 구현할 수 있는 가장 덜 강력한 어드바이스 타입을 사용하는 것이 좋습니다. 예를 들어, 메소드의 반환 값으로 캐시를 업데이트하기만 하면 되는 경우 around 어드바이스가 동일한 작업을 수행할 수 있지만 around 어드바이스보다 after returning 어드바이스를 구현하는 것이 더 좋습니다. 가장 구체적인 어드바이스 타입을 사용하면 오류 가능성이 적은 간단한 프로그래밍 모델이 제공됩니다. 예를 들어, 어라운드 어드바이스에 사용되는 JoinPoint
에서는 proceed()
메소드를 호출할 필요가 없으므로 호출에 실패할 수 없습니다.
모든 어드바이스 매개변수는 정적으로 타입이 지정되므로 Object
배열이 아닌 적절한 타입(예: 메소드 실행의 반환 값 타입)의 어드바이스 매개변수로 작업할 수 있습니다.
포인트컷과 매칭되는 조인 포인트 개념은 AOP의 핵심이며, 이는 가로채기(interception)만 제공하는 이전 기술과 구별됩니다. 포인트컷을 사용하면 객체 지향 계층 구조와 독립적으로 어드바이스를 타겟팅할 수 있습니다. 예를 들어, 선언적 트랜잭션 관리를 제공하는 around 어드바이스를 여러 객체(예: 서비스 계층의 모든 비즈니스 작업)에 걸쳐 있는 메서드 집합에 적용할 수 있습니다.