관점 지향 프로그래밍이라고도 불린다.
어떤 로직을 기준으로 핵심적인 관점, 부가적인 관점으로 나눠보고 그 관점을 기준으로 각각 모듈화 하겠다는 의미.
컴파일
⇒ [A.java](<http://a.java>) —-(AOP) —→ A.class(AspectJ)
바이트코드 조작
⇒ [A.java](<http://a.java>) → A.class —-(AOP)—→ 메모리
(AspectJ)
프록시패턴과는 다르게 바이트코드 조작
방식은 타깃 오브젝트를 뜯어고쳐서 부가기능을 직접 넣어주는 직접적인 방법을 택한다.
AspectJ
는 프록시와는 다르게 좀 더 직접적인 방법으로 부가기능을 제공하는데, 컴파일된 Target
의 클래스 파일 자체를 수정하거나 클래스가 JVM에 로딩되는 시점을 가로채 바이트코드를 조작하는 방법을 사용한다. 그렇기 때문에 .java
파일과 .class
파일을 비교해보면 내용이 달라진걸 확인할 수 있다.
해당 방법(바이트코드 조작
)을 사용하는 이유는 두가지가 있다.
스프링과 같은 DI컨테이너의 도움을 받지 않아도 AOP를 적용할 수 있기 때문이다. 그렇기에 스프링과같은 컨테이너가 사용되지 않는 환경에서도 손쉽게 AOP의 적용이 가능해진다.
프록시 방식보다 강력하고 유연한 AOP가 가능하다.
프록시를 AOP의 핵심 메커니즘으로 사용할 경우 부가기능(공통 모듈)을 부여할 대상은 클라이언트가 호출할 때 사용하는 메소드로 제한된다.
하지만, 바이트코드 조작
방식을 사용하면, 오브젝트의 생성, 필드 값 조회및 조작, 스태틱 초기화 등 다양한 작업에 부가기능을 부여할 수 있다.
이처럼 프록시를 사용한 AOP에서는 불가능한 부분에서까지 부가기능 부여가 가능하기 때문에 강력하고 유연하다.
프록시 패턴(스프링 AOP가 사용하는 방법)
⇒ 공통 모듈을 프록시로 만들어서 DI
로 연결된 빈 사이에 적용해 Target
의 메소드 호출 과정에 참여애 부가기능(공통 모듈)을 제공해준다.
그렇기의 JDK
와 Spring Container
외에 특별한 기술 및환경을 요구하지 않는다.
Advice
가 구현하는 MethodInterceptor
인터페이스는 다이내믹 프록시의 InvocationHandler
와 마찬가지로 프록시부터 메소드 요청정보를 전달받아 타깃 오브젝트의 메소드를 호출하는데, 이렇게 메소드를 호출하는 전/후로 부가기능(공통 모듈)을 제공할 수 있다.
이런식으로 독립적으로 개발한 부가기능 모듈을 다양한 타깃 오브젝트의 메소드에 다이내믹하게 적용해주기 위해 가장 중요한 역할을 맡고 있는게 프록시고, 스프링 AOP는 프록시 방식의 AOP라 할 수 있다.
Aspect
⇒ 여러곳에서 쓰이는 공통 부분 코드를 모듈화한 것
Target
⇒ Aspect가 적용되는 곳(Ex: Class
, Method
...)
Advice
⇒ Aspect 에서 실질적인 기능에 대한 구현체
Joint point
⇒ Advice 가 Target에 적용되는 시점
⇒ 메서드 진입할 때, 생성자 호출할 때, 필드에서 값을 꺼낼 때 등
Point cut
⇒ Joint Point 의 상세 스펙을 정의한 것