Aspect Object Programming, 즉 관점지향 프로그래밍을 의미하며 어떤 로직을 기준으로 핵심적인 관점, 부가적인 관점(횡단 관심사)으로 나누어 각각 모듈화하겠다는 프로그래밍 패러다임입니다.
애플리케이션의 핵심기능을 담고 있지는 않지만, 애플리케이션을 구성하는 중요한 한 가지 요소이고, 핵심기능에 부가되어 의미를 갖는 특별한 모듈을 애스펙트(Aspect) 라고 합니다.
객체지향 관점에서는 독립적인 모듈화가 불가능한 트랜잭션 경계설정 과 같은 부가기능을 관점지향 관점에서는 중복되는 횡단 관심사를 분리하여 모듈화시킬 수 있습니다.
부가기능이 핵심기능의 모듈에 섞여있어서 지저분한 설계와 코드의 상태라면, 핵심기능인 사용자 관리 로직을 파악하고, 수정하고, 테스트하기가 매우 불편하게 됩니다.
독립 애스펙트를 이용한 부가기능의 분리와 모듈화
위 그림과 같이 독립된 측면에 존재하는 애스펙트로 분리함으로써, 핵심 기능은 그 기능을 담은 코드로만 존재하여 코드의 가독성과 유지보수성을 높일 수 있습니다. 이러한 방식으로 AOP는 객체지향적인 가치를 유지하면서도 중복되는 횡단 관심사를 효과적으로 처리할 수 있도록 도와줍니다.
결론적으로, AOP는 애스펙트를 분리함으로써 핵심기능을 설계하고 구현할 때 객체지향적인 가치를 지킬 수 있도록 도와주는 것이라고 볼 수 있습니다.
타깃 (Target)
타깃은 부가기능(공통 관심사)을 부여할 대상을 의미합니다.
핵심기능을 담은 클래스일 수도 있지만 경우에 따라서는 다른 부가기능을 제공하는 프록시 오브젝트일 수도 있습니다. 다라서 부가 기능을 부여할 대상이 되는 클래스가 '타깃' 이라고 이해하는 것이 일반적입니다.
포인트컷 (Pointcut)
Advice를 적용할 메소드를 선정하는 알고리즘
프록시를 적용할 클래스인지 판단하여 적용 대상 클래스라면 어드바이스를 적용할 메소드인지 확인하는 식으로 동작합니다. 결국 두 가지 조건 모두 충족되는 타깃의 메소드에 어드바이스가 적용됩니다.
스프링의 AspectJExpressionPointcut을 빈으로 등록하고 expression 프로퍼티에 포인트컷 표현식을 넣어주면 됩니다. (코드 작성 X)
@Transactional로 트랜잭션 속성이 부여된 오브젝트라면 포인트컷의 선정 대상이 됩니다.
어드바이스 (Advice)
어드바이스는 타깃에 제공할 부가기능을 담은 모듈입니다. 오브젝트로 정의하기도 하지만 메소드 레벨에서 정의할 수도 있습니다.
MethodInterceptor처럼 메소드 호출 과정에 전반적으로 참여하는 것도 있지만, 예외가 발생했을 때만 동작하는 어드바이스처럼 메소드 호출 과정의 일부에서만 동작하는 어드바이스도 있습니다.
조인 포인트 (Joinpoint)
어드바이스가 적용될 수 있는 위치를 말합니다.
스프링의 프록시 AOP에서 조인 포인트는 메소드의 실행 단계뿐입니다. 타깃 오브젝트가 구현한 인터페이스의 모든 메소드는 조인 포인트가 됩니다.
프록시 (Proxy)
프록시는 클라이언트와 타깃 사이에 투명하게 존재하면서 부가기능을 제공하는 오브젝트입니다. DI를 통해 타깃 대신 클라이언트에게 주입되며, 클라이언트의 메소드 호출을 대신 받아서 타깃에 위임해주면서, 그 과정에서 부가기능을 부여합니다. 스프링은 프록시를 이용해 AOP를 지원합니다.
어드바이저 (Advisor)
어드바이저는 포인트것과 어드바이스를 하나씩 갖고 있는 오브젝트 입니다.
어드바이저는 어떤 어드바이스를 어디에 전달할 것인가를 알고 있는 AOP의 가장 기본이 되는 모듈입니다.
스프링에서 어드바이저는 자동 프록시 생성기인 DefalutAdvisorAutoProxyCreator에 의해 자동수집되고, 프록시 대상 선정 과정에 참여하며, 자동생성된 프록시에 다이내믹하게 DI 돼서 동작하는 어드바이저가 됩니다. 스프링 AOP에서만 사용되는 특별한 용어이며, 일반적인 AOP에서는 사용되지 않습니다.
애스펙트 (Aspect)
OOP의 클래스와 마찬가지로 AOP의 기본 모듈입니다.
여러 개의 포인트컷과 어드바이스의 조합으로 만들어지며 보통 싱글톤 형태의 오브젝트로 존재합니다. 스프링의 어드바이저는 아주 단순한 애스펙트 라고 볼 수 있습니다.
참고
[도서] 토비의 스프링 1