Choosing which AOP Declaration Style to Use
특정 요구 사항을 구현하기 위해 애스펙트가 최선의 접근 방식이라고 결정했다면, Spring AOP와 AspectJ 중 무엇을 사용할지, 그리고 Aspect 언어(코드) 스타일, @AspectJ 애너테이션 스타일, Spring XML 스타일 중 어떤 것을 사용할지 결정해야 합니다. 이러한 결정은 애플리케이션 요구 사항, 개발 도구, 팀의 AOP에 대한 친숙도 등 여러 요인에 영향을 받습니다.
Spring AOP 또는 Full AspectJ?
가장 간단하게 작동할 수 있는 것을 사용하세요. Spring AOP는 Full AspectJ를 사용하는 것보다 간단합니다. 개발 및 빌드 프로세스에 AspectJ 컴파일러/위버를 도입할 필요가 없기 때문입니다. Spring 빈의 작업 실행에만 조언(advice)을 적용해야 한다면 Spring AOP가 적합합니다. Spring 컨테이너가 관리하지 않는 객체(일반적으로 도메인 객체)나 메서드 실행 외의 조인 포인트(예: 필드 get 또는 set 조인 포인트 등)에 조언을 적용하려면 AspectJ를 사용해야 합니다.
AspectJ를 사용하는 경우, AspectJ 언어 문법(코드 스타일이라고도 함) 또는 @AspectJ 애너테이션 스타일을 선택할 수 있습니다. 애스펙트가 설계에서 중요한 역할을 하며 Eclipse의 AspectJ Development Tools(AJDT) 플러그인을 사용할 수 있다면 AspectJ 언어 문법이 더 선호됩니다. 이는 애스펙트를 작성하기 위해 설계된 언어로 더 간결하고 단순하기 때문입니다. Eclipse를 사용하지 않거나 애스펙트가 몇 개만 있고 애플리케이션에서 중요한 역할을 하지 않는 경우, @AspectJ 스타일을 고려할 수 있습니다. 이 경우 일반 Java 컴파일을 IDE에서 사용하고 빌드 스크립트에 애스펙트 위빙 단계를 추가하면 됩니다.
Spring AOP에서 @AspectJ 또는 XML?
Spring AOP를 사용하기로 결정했다면, @AspectJ 스타일과 XML 스타일 중 선택할 수 있습니다. 이와 관련하여 다양한 트레이드오프를 고려해야 합니다.
XML 스타일은 기존 Spring 사용자에게 가장 익숙할 수 있으며, 진정한 POJO로 지원됩니다. AOP를 엔터프라이즈 서비스를 구성하는 도구로 사용하는 경우 XML이 좋은 선택이 될 수 있습니다(포인트컷 표현식이 독립적으로 변경 가능한 구성의 일부로 간주되는 경우가 좋은 테스트입니다). XML 스타일을 사용하면 시스템에 어떤 애스펙트가 있는지 구성을 통해 더 명확하게 알 수 있습니다.
그러나 XML 스타일에는 두 가지 단점이 있습니다. 첫째, XML 스타일은 다루는 요구 사항의 구현을 단일 위치에 완전히 캡슐화하지 않습니다. DRY 원칙은 시스템 내의 어떤 지식에 대해서도 단일하고 명확하며 권위 있는 표현이 있어야 한다고 말합니다. XML 스타일을 사용하면 요구 사항 구현에 대한 지식이 백업 빈 클래스 선언과 구성 파일의 XML로 나뉩니다. 반면, @AspectJ 스타일을 사용하면 이 정보가 애스펙트라는 단일 모듈에 캡슐화됩니다. 둘째, XML 스타일은 @AspectJ 스타일에 비해 표현할 수 있는 것이 약간 더 제한적입니다. 예를 들어, XML 스타일은 "singleton" 애스펙트 인스턴스화 모델만 지원하며, XML에서 선언된 명명된 포인트컷을 결합할 수 없습니다. @AspectJ 스타일에서는 다음과 같은 포인트컷을 작성할 수 있습니다:
@Pointcut("execution(* get*())")
public void propertyAccess() {}
@Pointcut("execution(com.xyz.Account+ *(..))")
public void operationReturningAnAccount() {}
@Pointcut("propertyAccess() && operationReturningAnAccount()")
public void accountPropertyAccess() {}
반면, XML 스타일에서는 첫 두 포인트컷만 선언할 수 있습니다:
<aop:pointcut id="propertyAccess" expression="execution(* get*())"/>
<aop:pointcut id="operationReturningAnAccount" expression="execution(com.xyz.Account+ *(..))"/>
XML 접근 방식의 단점은 이러한 정의를 결합하여 accountPropertyAccess
포인트컷을 정의할 수 없다는 점입니다.
@AspectJ 스타일은 추가적인 인스턴스화 모델과 더 풍부한 포인트컷 구성을 지원합니다. 또한 애스펙트를 모듈 단위로 유지하는 장점이 있습니다. @AspectJ 애스펙트는 Spring AOP와 AspectJ 모두에서 이해되고 사용될 수 있다는 장점도 있습니다. 따라서 추가적인 요구 사항을 구현하기 위해 AspectJ의 기능이 필요하다고 판단되면, 클래식 AspectJ 설정으로 쉽게 마이그레이션할 수 있습니다. 일반적으로 Spring 팀은 엔터프라이즈 서비스의 단순한 구성을 넘어선 커스텀 애스펙트를 위해 @AspectJ 스타일을 선호합니다.