티스토리 뷰


자바의 AOP를 알아보면서 허접하게나마 각 사용방법을 훑은 것 같습니다. 최종적으로 AspectJ가 남았습니다. 이제 이놈만 정복하면 될 듯 합니다. 끝판왕이니 만큼 심혈을 기울여 조사하고 공부하고 깨우치도록 해봅시다.

자바 AOP - AspectJ에 대해서 - Java AOP #5

AspectJ란?

AspectJ는 PARC에서 개발한 자바 프로그래밍 언어용 관점 지향 프로그래밍 (AOP) 확장 기능이다. 이클립스 재단 오픈 소스 프로젝트에서 독립형 또는 이클립스로 통합하여 이용 가능하다. AspectJ는 최종 사용자를 위한 단순함과 이용성을 강조함으로써 폭넓게 사용되는 AOP에 대한 디 팩터 표준(사실 상 표준)이 되었다.

 

이전 포스팅에서도 AspectJ에서 두가지 방식으로 aop를 사용할 수 있다고 언급했습니다.

 

머 암튼 aspect 지향 프로그래밍의 구현이랄 수 있는데
AJC(AspectJ용 컴파일러)로 컴파일 시 바이트코드를 직접적으로 넣을 수 있는 CTW( Compile Time Weaving)방식을 사용할 수 있고 직접적으로 클레스 파일에 수정을 가하는 방식이기 때문에 가장 속도가 빠를수밖에 없다고 합니다. 물론 LTW(Load Time Weaving)방식을 선택해서 사용할 수 있지만 굳이 쓸 이유가 없어보입니다.

 

AspectJ 사용 환경세팅 구성

먼저 환경세팅부터 필요하다. 이클립스에서는 AspectJ를 편하게 사용할 수 있게 AJDT 플러그인이 개발되어있다. 이클립스 찬양해~ 이곳에서 이클립스 버전 별로 AJDT 플러그인을 다운로드 할수 있는 주소를 알 수 있다. https://www.eclipse.org/ajdt/downloads/

 

AJDT Downloads | The Eclipse Foundation

The Eclipse Foundation - home to a global community, the Eclipse IDE, Jakarta EE and over 375 open source projects, including runtimes, tools and frameworks.

www.eclipse.org

이 AJDT 플러그인을 설치하고 프로젝트를 선택 우클릭 -> configure -> convert to AspectJ Project를 선택해서 AspectJ 를 시작할 수 있다.

 

프로젝트를 선택 우클릭 -> configure -> convert to AspectJ Project를 선택해서 AspectJ 를 시작


이제 프로젝트에 AspectJ Runtime Library가 추가된다.

 

프로젝트에 AspectJ Runtime Library가 추가


기존에 열심히 만들었던 예제를 가지고 aspectj를 이용해보자. 소스에서 new를 해서... Aspect를 만든다.

 

소스에서 new를 해서... Aspect를 만든다.


'Exam04_AspectJ'로 만들었다. 확장자가 기본 자바파일과 다르게 *.aj로 만들어지는 것을 확인할 수 있었다.

막상 만들어놓고 봤는데 어떻게 시작해야할지 모르겠다. 개념이 없어서 그렇겠지. 이럴 때는 간단한 설명을 보고 바로 실습하는 것이 좋다.


1. 함수와 변수를 AspectJ로 만들어보자.

java 파일에 없는 내용을 class 파일로 컴파일 시 넣어주는 것이다. AJC(AspectJ Compiler)의 역할을 바로 눈으로 확인하고 싶었다.

 

우선 예제 소스를 만들어본다. Exam04_AspectJ.java

 

package test;

public class Exam04_AspectJ {
    public static void main(String[] args) {        
        AspectJ_Test1 at = new AspectJ_Test1();
        System.out.println(at.name); 
        at.say();
        
    }
}
class AspectJ_Test1 {
    
    
}

다음은 aspectJ 파일이다. Exam04_AspectJW.aj 로 다음 내용을 만든다.

 

package test;
public aspect Exam04_AspectJW {
    
    public String AspectJ_Test1.name = "nhj12311";
    
    public void AspectJ_Test1.say(){
        System.out.println("Hello");
    }
}

Exam04_AspectJW.aj 내에서 AspectJ_Test1의 필드와 함수를 선언하고 있다. 컴파일된 class 파일을 디컴파일해서 열어봤다.

AspectJ_Test1.class의 디컴파일된 내용 : 선언하지도 않은 name 필드와 say함수가 만들어져있다.

 

 

어떤가. 재밌지 않은가? 컴파일 시에 내 의도대로 class 파일을 조작하다니. 컴파일 시에 조작되기 때문에 러닝타임에 속도저하는 전혀 없을 것이라는 생각을 할 수 있다. AspectJ_Test1.java에 없는 함수와 필드를 만들어 넣을 수 있다. 다른 것도 가능하다고 하나 이정도 알고 넘어가면 되지 싶다.


2. AspectJ 조인 포인트? 이것은 먹는것인가...?

아무래도 횡단관심사(Cross Cutting Concern)에 대해서 걸어 낼 수 있는 지점을 말하는 듯 하다. 아래 그림과 같이 다양한 조인포인트를 갖는다. 함수를 콜할 때 생성자가 불려질 때 필드가 지정되거나 등...

 

무튼... 이런 지점을 잡아내서 내가 원하는 코드를 실행할 수 있다가 요인것 같다. 이런 식이다. 명명 패턴을 지정해서 이름이 set으로 시작하는 AspectJ_Test2형 객체의 함수를 콜하는 규칙을 지정할수 있다.

 

pointcut pc_say(AspectJ_Test2 p): target(p) && call(void AspectJ_Test2.set*());

3. AspectJ 어드바이즈는 또 뭐란 말인가?

 

이건 2번에서 이야기한 조인 포인트의 조건이 적용되는 시점의 앞이나 뒤에 내가 원하는 코드를 넣을 수 있다. 로깅 처리나 공통 처리 부분, 보안, 트랜잭션 관리에 대한 처리에 활용 가능하다는 이야기다. 바로 간단한 예제를 만들어보자.

 

Exam04_AspectJW2.aj

 

package test;
public aspect Exam04_AspectJW2 {
    pointcut pc_say(AspectJ_Test2 p): target(p) && call(void AspectJ_Test2.set*()); 
    before(AspectJ_Test2 p) : pc_say(p) {
        System.out.println("before Say!");
    }   
    after(AspectJ_Test2 p) : pc_say(p) {
        System.out.println("after Say!");
    }
}

Exam04_AspectJ2.java

 

package test;

public class Exam04_AspectJ2 {
    public static void main(String[] args) {        
        AspectJ_Test2 at = new AspectJ_Test2();     
        at.setSay();        
    }
}
class AspectJ_Test2 {
    public void setSay(){
        System.out.println("Hello!");
    }   
}

실제로 이런 코딩으로 aspectJ를 적용하면 AJDT가 적용된 경우 이클립스에서는 화살표로 advides 표시를 보여준다.

aspectJ파일

 

aspectJ파일


Java 파일

Java 파일

출력결과 :

beforeSay!

Hello!

after Say!


궁금해서 만들어진 클레스 파일을 보니 Exam04_AspectJW2.aj가 Exam04_AspectJW2.class로 만들어진 것을 확인할 수 있었다. 바로 디컴파일 해서 보는 화면이다. AspectJ 파일인 aj 파일이 클래스로 변환될 때 어노테이션을 사용하는 방식으로 변환되는 것을 알수 있다.

 

AspectJ 파일인 aj 파일이 클래스로 변환될 때 어노테이션을 사용하는 방식으로 변환되는 것을 알수 있다.


그럼 Exam04_AspectJ2.java는 어떻게 만들어졌을까? 아래 화면은 Exam04_AspectJ2.class파일을 디컴파일 해서 열어본 모습이다. 보이는가? 클레스 파일에서 before와 after 함수가 바로 호출된다. 프록시니 리플렉션이니 전혀 사용하지 않는다. 이러니 빠를 수밖에... +_+

 

AspectJ를 통해 컴파일된 Exam04_AspectJ2.java

AspectJ를 통해 컴파일된 Exam04_AspectJ2.java


이렇게 자바 AOP, Spring에 적용된 AOP를 이해해보기 위해서 JDK Dynamic Proxy와 ASM, CGLIB, AspectJ까지 모두 개념적인 이해를 위해서 샘플 예제들을 만들어봤다. 개인적으로 AspectJ에 CTW가 가장 마음에 들고 AspectJ를 사용할수 없다면 CGLIB를 이용하게 될 것 같다. 


댓글
최근에 올라온 글
최근에 달린 댓글