비록 시작은 코딩일기지만, 그 끝은 창대하게
어엿한 개발자 블로그로 성장할 수 있도록.
본 게시글은
Endless Creation Spring Study
에 사용하는 자료입니다.
Aspect Oriented Programming
Spring AOP는 AOP의 구현체를 제공하며, Java에 이미 구현되어 있는 AspectJ 와 연동할 수 있는 기능 또한 제공한다. 그리고 Spring 자체에서 구현한 Spring AOP의 기능을 활용할 수 있게 해주고 있다(Spring Transaction
, Cache
).
Spring AOP 와 AspectJ는 다르다.
AspectJ
는 매우 다양한 Join Point
와 많은 기능을 제공하지만 Spring AOP
는 상당히 국한적으로 제공된다.OOP
를 보완하는 수단으로 흩어진 Aspect
를 모듈화 할 수 있는 프로그래밍 기법.
Crosscutting Concerns, 흩어진 관심사를 한 곳에 모으는 것이다.
가장 대표적인 예로는 Transaction
과 성능분석
등이 있다.
AOP의 구현체는 여기서 자세하게 확인 할 수 있다.
먼저 주요 용어와 의미는 다음과 같다.
그리고 AOP가 적용되는 전체적인 그림은 다음과 같다.
그림을 바탕으로 주요 용어를 간단하게 설명하자면,
Aspect
:: Aspect X, Aspect Y, Aspect Z 처럼 모듈화 한 것.
이 안에 Advice
와 Pointcut
이 들어간다.
Advice
:: 해야할 일들. 그림에서 색띠.
Pointcut
:: 어디에 적용되야 하는지에 대한 정보. 그림에서 A, B, C 등이 적힌 띠.
Target
:: 적용이 되는 대상. 그림에서 Class A, Class B, Class C 등
Join Point
:: 합류점.
실질적으로 가장 흔하게 사용하는 Join Point
는 메서드 실행 시점이다.
Pointcut
을 적용할 수 있는 합류점들을 의미한다. 즉, 일종의 Spec(명세) 이다.
Pointcut
이 바로 Join Point
의 구체적인 부분집합이다.
AOP가 적용되는 방법에는 다음 세 가지가 있다.
컴파일
:: .java
파일을 .class
파일로 만들 때 AOP가 적용된 Byte Code
로 조작하는 방법.
로드 타임
:: 순수하게 Compile 을 하고, Class 를 Loading 하는 시점에 Class 정보를 변경하는 방법(load time weaving).
런타임
:: Spring AOP가 사용하는 방식.
런타임때 어떤 Bean
에다가 어떤 Aspect
가 적용되는지 Spring
이 이미 알고 있다.
예를 들어, A Class 타입의 Bean
을 만들때 해당 Class 타입의 Proxy Bean
을 만든 다음, 그 Proxy Bean
이 Aspect
를 수행하고 그 다음 대상 객체인 A Class 타입의 Bean
을 호출하는 방법.
현실적으로 런타임
방식을 다음과 같은 이유로 자주 사용하게 될 것이다.
문법이 쉽다는 점
별도의 Weaver
같은 Java Agent
를 핸들링 하지 않아도 되는 점
별도의 설정 등을 하지 않는 다는 점
하지만, 컴파일
, 로드 타임
방식의 AspectJ
의 매우 많은 기능 제공 때문에 필요할때 연동하여 같이 쓰는 경우도 존재한다.
Spring AOP 는 Proxy
기반의 AOP 구현체이고 Spring Bean
에만 적용이 가능하다.
모든 AOP의 기능 제공이 목적이 아니라, Spring IoC
와 연동하여
Enterprise Application 에서 가장 흔한 문제에 대한 해결책 제공이 목적이다.
Proxy Pattern
::
Decorator pattern VS Proxy Pattern
Proxy Pattern
:: Proxy Class
와 Real Class
의 관계가 컴파일타임
에 정해진다.Decorator pattern
:: 런타임
에 정해진다.그리고 프록시 패턴은 Real Class의 접근에 대한 제어를 목적으로하며, 데코레이터 패턴은 Real Class의 기능에 다른 기능을 추가하는 목적으로합니다.
Proxy Pattern
은 위 그림과 같다. Client
는 Interface
타입으로 Proxy
객체를 사용하게 된다. 그리고 Proxy
객체는 원래 객체를 호출하게 된다.
즉, Proxy
객체가 Real Subject
객체를 감싸서 실제 Client
의 요청을 처리하게 된다.
이러한 패턴을 사용하는 이유는 기존 코드의 변경없이 접근 제어 또는 부가 기능을 추가할 수 있기 때문이다.
그런데 이 Proxy Pattern
을 위해서 매번 Proxy
클래스를 만들어야 하는지, 여러 클래스에 여러 메소드를 적용하기 위해선 어떻게 해야하는지, 객체들의 관계는 어떻게 정리할 건지에 대한 문제점이 있다.
그래서 등장한것이 바로 Spring AOP
이다.
Spring IoC Container
가 제공하는 기능과 Dynamic Proxy
를 사용하여 여러 복잡한 문제를 해결해준다.
AbstractAutoProxyCreator
라는 BeanPostProcessor Interface
의 구현체가 Bean Instance
를 만든 다음에 그것을 감싼 AOP Proxy Bean
을 만드는 역할을 한다.