Spring AOP는 개발자가 마주한 공통적인 문제를 해결하고자 Spring IoC를 통한 간단한 AOP구현이 목적, 완전한 AOP를 의도한 것이 아니며, Spring Container에 의해 관리되는 Beans에만 적용 가능
AspectJ는 완전한 AOP를 제공하는 것이 목적인 근원적인 AOP 기술, Spring AOP보다 강력하지만 복잡(AspectJ는 모든 객체에 적용이 가능)
AspectJ와 Spring AOP 동작과 성능에 영향을 주는 각기 다른 방식의 Weaving 사용
AspectJ는 세가지 방식의 Weaving을 사용 가능
AspectJ가 컴파일 시점과 로드 시점 Weaving을 사용하듯이, Spring AOP는 런타임 Weaving 사용
Spring AOP는 Proxy 기반 AOP 프레임워크, 대상 객체에 Aspect를 적용하기 위해선 대상 객체의 Proxy를 생성
AspectJ는 클래스들이 Aspect와 함께 컴파일되기 때문에 런타임시에는 아무것도 하지 않는다. 또한 어떤 디자인 패턴도 요구하지 않고 Aspect를 코드에 Weaving 하기 위해, AspectJ compiler(ajc)라는 컴파일러를 도입
Spring AOP는 메서드 실행헤만 JoinPoint를 지원하나 AspectJ는 런타임 이전에 실제 코드에 Cross-Cutting Concerns를 Weaving
Sprig AOP에서 동일 클래스 내 메서드 호출을 대상으로 Aspect 적용이 지원하지 않는데 동일 클래스 내 다른 메소드를 호출할 떄 Spring AOP에서 제공하는 Proxy 메소드가 호출되지 않기 떄문. 만약 기능적으로 피룡하다면 메소드를 각기 다른 Beans로 분리하던가 AspectJ를 사용
JoinPoint | SpringAOP | AspectJ |
---|---|---|
메서드 호출 | X | O |
메서드 실행 | O | O |
생성자 호출 | X | O |
생성자 실행 | X | O |
Static 초기화 실행 | X | O |
객체 초기화 | X | O |
필드 참조 | X | O |
필드 값 변경 | X | O |
핸들러 실행 | X | O |
Advice 실행 | X | O |
Spring AOP는 구현 시에 다른 외장 컴파일러를 필요하지 않기에 훨씬 간편, AspectJ를 사용하기 위해선 AspectJ compiler(ajc)라는 컴파일러를 도입해야 하고 모든 라이브러리들을 재 패키징 해야 함
컴파일 시점 Weaving은 런타임 Weaving에 비해 훨씬 빠르다. Spring AOP는 애플리케이션 시작 시 생성된 Proxy들을 기반으로 한 프레임워크로 성능에 악영향을 주는 훨씬 적인 수의 메소드만 지원하는 반면 AspectJ는 Aspect를 애플리케이션이 실행되기 전에 Weaving하기에 Spring AOP와는 달리 런타임 시 과부하가 없다.(여담으로 AspectJ가 Spring AOP보다 8배에서 35배 가까이 빠른다는 벤치마킹 결과가 있다)
Spring AOP | AspectJ |
---|---|
순수 Java로만으로도 구현 | 추가 도구(자바 프로그램)를 통해 구현 |
복잡한 과정이 필요 없음 | 로드 시점 Weaving을 사용하더라도 AspectJ compiler(ajc) 가 필요 |
런타임 Weaving만 가능 | 런타임 Weaving 불가능. 컴파일 시점/컴파일 전/로드 시점 Weaving을 지원 |
메소드 레벨의 Weaving만 지원 | 필드, 메소드, 생성자, final클래스/메소드 등 다양하게 지원 |
Spring Container에 의해 관리되는 빈즈에만 적용할 수 있음 | 모든 객체를 대상으로 적용 가능 |
메소드 실행 Point cut만 지원 | 모든 Point cut을 지원 |
대상 객체의 Proxy가 생성되고 Aspect는 이러한 Proxy를 대상으로 적용 | Aspect는 애플리케이션이 실행되기 전에 코드에 바로 Weaving됨(런타임 이전) |
AspectJ에 비해 훨씬 느림 | Spring AOP에 비해 좋은 성능 |
배우고 적용하기 쉽다 | Spring AOP에 비해 복잡 |