AOP(Aspect Oriented Programming)의 약자로, 여러 객체에 공통적으로 적용할 수 있는 기능을 따로 정의해서 코드의 재사용성을 높여주는 프로그래밍 기법임. AOP의 기본적인 개념은 따로 정의항 공통 기능을 다른 객체에 삽입하는 것이다. OOP(Object Oriented Programming)과는 반대되는 개념이라기 보다는 OOP를 보완해주는 프로그래밍 기법이라 할 수 있다.
그림에서 보는 것과 같이 Class A, Class B, Class C 에는 공통적을 들어가는 기능이 있다고 한다. 그럼 이 공통적인 기능은 Aspect X, Aspect Y, Aspect Z로 따로 분류해서 어노테이션등으로 Class에 각각 적용할 수 있으면 코드 재사용률을 높이고 유지보수도 매우 쉬울 것이다. 이것이 간단하게 그림으로 본 AOP임.
Join Point - Advice를 적용 가능한 지점을 의미한다. 메서드 호출, 필드 값 변경 등이 Join Point에 해당하며, 스프링은 프록시를 이용해서 AOP를 구현하기 때문에 메서드 호출에 대한 Join point만 지원.
Point Cut - JoinPoint의 부분 집합으로서 실제로 Advice가 적용되는 Join point를 나타낸다. 스프링에서는 정규 표현식아나 AspectJ의 문법을 이용하여 Pointcut을 정의할 수 있다. 즉, joint point는 적용 가능한 스팩에 가깝고 point cut은 실제 해당 advice가 적용되는 위치라 할 수 있다.
Advice - 언제 공통 관심 기능을 핵심 로직에 적용할 지를 정의한 로직. 예를 들어, '메서드를 호출하기전' (언제)에 트랜잭션 시작' (공통 기능) 기능을 적용한다는 것을 정의함.
Weaving - Advice를 핵심 로직 코드에 끼워 넣는 것을 weaving 이라고 한다.
Aspect - 여러 객체에 공통으로 적용되는 기능을 Aspect라고 한다. 트랜잭션이나 보안 등이 Aspect의 예라고 할 수 있다.
AOP가 적용되는 시간은 3가지로 볼 수 있다.
컴파일 타임 - 자바코드가 컴파일 되어서 .class파일로 컴파일 될때 끼워넣는 방법
로드 타임 - 자바코드가 컴파일 될때는 순수한 class AOP의 코드가 끼워넣지 않은 코드이지만. JVM에 로드 될때 AOP의 코드를 끼워 넣는 방법
런타임 - 말그대로 자바 파일이 컴파일 되고, JVM에 로드도 다 되고 나서 실행중일때 AOP의 코드가 끼워 넣어 지는 방법
AOP를 구현하는 구현체는 자바에서 구현한 AspectJ 라이브러리와 Spring AOP가 있다.
차이점을 알아보기 전에 결론부터 말하자면 AspectJ가 더 많은 기능을 가지고 있고 Spring AOP는 제한적이다.
자, 이제 다각도에서 차이점을 아라보자!
Weaving | Spring AOP | AspectJ |
---|---|---|
컴파일 타임 | 불가능 | 가능 |
로드 타임 | 불가능 | 가능 |
런타임 | 가능 | 불가능 |
Join Point | Spring AOP | AspectJ |
---|---|---|
메서드 호출 | X | O |
메서드 실행 | O | O |
생성자 호출 | X | O |
생성자 실행 | X | O |
Static 초기화 실행 | X | O |
객체 초기화 | X | O |
필드 참조 | X | O |
필드 값 변경 | X | O |
핸들러 실행 | X | O |
Advice 실행 | X | O |
컴파일 타임이나 로드타임에 weaving 할 수 있는 AspectJ가 성능이 훨씬 좋다.
Spring AOP같은 경우 런타임시에 빈들을 읽어서 AOP가 적용 되 있을 경우 해당 객체를 Proxy들을 기반으로 AOP를 구현했기 때문에 성능상으로는 런타임시에 어떠한 과부하도 주지 않는 AspectJ가 더 성능이 좋다.
Spring AOP | AspectJ |
---|---|
순수 자바로만 구현됨 | 추가 도구(자바 프로그램)을 통해 구현 됨 |
복잡한 과정이 필요없음 | 로드 시점에 weaving하더라도 AspectJ컴파일러가 필요함 |
런타임 weaving만 가능 | 런타임 weaving만 불가능 |
메서드 레벨의 weaving만 지원함 | 필드, 메서드 생성자, final클래스, 메서드 등 다양하게 지원함 |
Spring Container에서 관리되는 bean에만 aop적용가능 | 모든 객체를 대상으로 적용 가능 |
메서드 실행 point cut만 지원함 | 모든 point cut을 지원함 |
대상 객체의 proxy가 생성되고 aspect는 proxy에 적용됨 | aspect는 어플리케이션이 실행되기 이전에 이미 weaving됨 |
AspectJ에비해 느림 | Spring AOP에 비해 성능이 좋음 |
배우고 적용하기가 쉬움 | Spring AOP에 비해 복잡함 |