Whiteship's Note


9. @AspectJ의 Pointcut 살펴보기 2

AOP : 2007. 1. 16. 17:36


참조 : http://www.eclipse.org/aspectj/doc/released/progguide/semantics-pointcuts.html

this(Type)
  • this 키워드에 바인딩 되는 현재 실행 중인 객체의 타입이 Type인 경우에 모든 메소드 execution Join point를 나타냅니다.
target(Type)
  • 메소드가 호출되거나 필드가 접근 되는 객체의 타입이 Type인 경우에 그 객체의 모든 메소드 execution Join point를 나타냅니다.
args( Type or ".." or * )
  • 메소드의 아규먼트가 () 안에 정의한 갯수나 타입에 매칭 되는 모든 메소드 exexution Join point를 나타냅니다.
@targer(Type)
  • 타켓 객체(메소드가 호출되거나 필드가 접근 되는 객체)에 @Type 어노테이션이 붙어있을 때 그 객체의 모든 메소드 execution Join point를 나타냅니다.
@within(Type)
  • 선언된 타입에 @Type 어노테이션이 붙어있을 때 그 객체의 모든 execution Join point를 나타냅니다.
@annotation(Type)
  • 실행되는 메소드에 @Type 어노테이션이 붙어있을 때 그 메소드의 execution Join point를 나타냅니다.
@args(Type)
  • 실행시 아규먼트로 넘겨지는 것에 @Type 어노테이션이 붙어있을 때 그 메소드의 execution Join point를 나타냅니다.
top

Write a comment.


8. @AspectJ의 Pointcut 살펴보기 1

AOP : 2007. 1. 16. 12:47


참조 : Spring Reference 6.2.3.4

execution(modifiers-pattern? ret-type-pattern declaring-type-pattern? name-pattern(param-pattern) throws-pattern?)
  • 빨간색으로 표시된 return type pattern을 제외 하고는 전부 optional입니다.
  • modifiers-pattern은 advice가 적용될 메소드의 접근 지시자 형태를 정합니다. * 은 모든 메소드 public은 public 메소드만... 뭐 그런 식입니다.
  • declaring-type-pattern은 인터페이스나 패키지 패턴을 나타내는 부분인듯 합니다.
  • name-pattern은 메소드의 이름의 형태를 지정해 줍니다. set* 과 같이 하면 set으로 시작하는 모든 메소드를 나타냅니다.
  • param-pattern은 조금 특이합니다. ()은 파라미터가 없는 메소드를 가리키고, (..)는 파라미터가 어떤 형태든 몇 개든 상관없슴을 나타냅니다. 다른 패턴들이 * 와일드 카드를 사용하는 것과는 차이가 있네요. (*, String) 이것은 파라미터가 두 개고 첫번 째 파라미터의 타입은 상관이 없고 두 번째 파라미터의 타입이 String인 메소드를 나타냅니다.
within(type-pattern)
  • within은 Spring AOP가 메소드 execution 포인트컷만 지원하기 때문에 해당 타입과 관련된 모든 메소드 실행시점을 가리키게 됩니다. AspectJ를 사용할 때는 훨씬 다양한 포인트컷[각주:1]을 나타내게 됩니다.
  • within(com.xyz.service.*) 이것 같은 경우는 com.xyz.service 패키지 안에 있는 모든 클래스의 모든 메소드의 실행 시점을 나타냅니다.
  1. 클래스 초기화 시점, 객체 초기화 시점, 생성자 실행 시점, 메소드 실행 시점 이밖에도 변수들에 대한 포인트컷까지 적용되며 내부 클래스가 있을 경우 그 것의 생성자나 기타 내부 클래스와 관련된 모든 join point에도 적용 됩니다. [본문으로]
top

Write a comment.


7. @AspectJ 사용하는 초간단 AOP 예제 2

AOP : 2007. 1. 13. 22:27


@AspectJ 를 사용하는 초간단 AOP 예제에서 Pointcut을 선언하고 Advice들에서 해당 Pointcut을 불러가며 사용했었습니다.

    @Pointcut("execution(public * ex1.Human.sayName(..))")
    public void greeting() {
    }

    @AfterReturning("greeting()")
    public void doBeforeOne() {
        System.out.println("AOP 죽~ 여~ 줍니다~");
    }

이렇게 했었는데요. AspectJ에서는 Anonymous Pointcut이라고 하는데 Spring AOP(중에서도@AspectJ)에서도 사용할 수 있습니다. 다음과 같이 Pointcut 이름을 적을 필요 없이 바로 적용될 부분은 Advice에 명시해 주면 됩니다.

    @AfterReturning("execution(public * Human.sayName(..))")
    public void doBeforeOne() {
        System.out.println("AOP 죽~ 여~ 줍니다~");
    }

두 개의 차이점은 위에 기존에 사용해 봤던 방식은 당연히 재사용이 편하다는 것. 그리고 아래의 것은 재사용하기 불편하다는 차이밖에 없는 것 같습니다. :)

Spring AOP를 JDK 6.0 에서 돌리지 마세요 ㅠ.ㅠ Pointcut이 있는데도 없다고 나옵니다. 이것 때문에 정말 황당해 하며 1시간 가량을...'저번에는 분명히 됐는데;; 왜이러지..' 하면서 괴로워 했습니다.
참조 : http://forum.springframework.org/showthread.php?p=92737

top

  1. Favicon of http://seal.tistory.com BlogIcon 물개선생 2007.01.15 08:21 PERM. MOD/DEL REPLY

    흠.. 그렇군요. JDK6에서 테스트를 해보지 않아서 몰랐습니다. 좋은 정보 감사드립니다. ^^*

    Favicon of https://whiteship.tistory.com BlogIcon 기선 2007.01.15 09:10 신고 PERM MOD/DEL

    넵~ 헤헷 :)
    좋은 하루 되세요~

  2. hsk741 2007.08.15 17:05 PERM. MOD/DEL REPLY

    Aspectjweaver.jar 버전 1.5.3에서는 작동하는군요

    Favicon of http://whiteship.tistory.com BlogIcon 기선 2007.08.15 23:07 PERM MOD/DEL

    관련 jar들은 Spring-with-depedencies.zip 에 있던 녀석들을 사용해서 버전은 확인을 못했었네요. :)

  3. Favicon of http://eerien.com/blog/ BlogIcon 이린 2008.01.30 13:12 PERM. MOD/DEL REPLY

    Spring AOP(중에서도@AspecJ)

    에 오타가 있네요. ^-^

    Favicon of https://whiteship.tistory.com BlogIcon 기선 2008.01.30 14:39 신고 PERM MOD/DEL

    감사합니다. (__)/
    수정했습니다.

Write a comment.


6. Join Points and Pointcuts

AOP : 2007. 1. 12. 17:51


참조 : http://www.eclipse.org/aspectj/doc/released/progguide/quick.html

Advice의 종류는 이전에 살펴 보았고 Join Point들은 위 링크에서 볼 수 있습니다. 위 링크에서 볼 수 있는 Join Point들은 AspectJ에서 지원 해주는 것들이고 Spring에서는 저 중에서 Method execution만 지원합니다. 이 내용은 Spring Reference 6.2.3.1 에서 확인 할 수 있습니다.

AspectJ In Action 2.4.2 에 나와있는 예제 소스 중에 실행 하는 소스의 모든 Join Point들에 before advice와 after advice를 적용할 수 있는 aspect 소스가 있습니다. 소스는 다음과 같습니다.

public aspect JoinPointTraceAspect {

       private int _callDepth = -1;

 

       pointcut tracePoints() : !within(JoinPointTraceAspect);

 

       before() : tracePoints() {

             _callDepth++;

             print("Before", thisJoinPoint);

       }

 

       after() : tracePoints() {

             print("After", thisJoinPoint);

             _callDepth--;

       }

 

       private void print(String prefix, Object message) {

             for (int i = 0, spaces = _callDepth * 2; i < spaces; i++) {

                    System.out.print(" ");

             }

             System.out.println(prefix + ": " + message);

       }

}

pointcut tracePoints() 는 Pintcut의 이름을 정의한 부분이고
!within(JointPointTraceAspect)는 JoinPointTraceAspect 클래스 이외의 모든 Joint Point들을 Pointcut으로 묶었습니다.

위 소스코드를 이 전에 실행 시켜 보았던 AspectJ를 사용한 초간단 AOP 예제에 같이 두고 돌려보면 콘솔창에 다음과 같이 여러 Join Point를 볼 수 있습니다.

top

Write a comment.


5. XML 사용하는 초간단 AOP 예제

AOP : 2007. 1. 9. 20:54


초간단 AOP 예제는 이것으로 세개 째군요.
이전에 올렸던 @AspectJ 사용하는 초간단 예제를 XML 설정 파일을 사용하도록 바꿔봤습니다.

다른 파일들은 모두 같고 MannerAOP파일에서 모든 어노테이션들을 띄어 내고 다음과 같이 수정했습니다.

public class MannerAOP {

       public void beforeSaying() {

             System.out.println("다시 소개 합니다~");

       }

 

       public void afterSaying() {

             System.out.println("AOP ~ 줍니다.");

       }

}

그리고 XML 설정 파일에서 저번에는
<aop:aspectj-autoproxy/>
이렇게 한 줄이 있었는데요. 이 것을 지우고 다음과 같이 설정합니다.

<beans xmlns="http://www.springframework.org/schema/beans"

       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"

       xmlns:aop="http://www.springframework.org/schema/aop"

       xsi:schemaLocation="

http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.0.xsd

http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-2.0.xsd">

 

       <!-- this is the object that will be proxied by Spring's AOP infrastructure -->

       <bean id="keesun" class="secondSpringAOP.Keesun" />

 

       <!-- this is the actual advice itself -->

       <bean id="manner" class="secondSpringAOP.MannerAOP" />

 

       <aop:config>

             <aop:aspect ref="manner">

 

                    <aop:pointcut id="greeting"

                           expression="execution(public * secondSpringAOP.Human.sayName(..))" />

 

                    <aop:before pointcut-ref="greeting" method="beforeSaying" />

 

                    <aop:after-returning pointcut-ref="greeting" method="afterSaying" />

 

             </aop:aspect>

       </aop:config>

 

</beans>

결과는 다음과 같습니다.

다시 한 번 소개 합니다~
저는 백~기~선입니다.
AOP 죽~여 줍니다.

이 예제를 돌리기 위해서는 이전에 추가했던 spring.jar, commons-logging.jar, aspectjrt.jar, aspectjweaver.jar 이 것들 이 외에 'Spring-with-dependencies 설치 폴더'/lib/asm/ 안에 있는 asm-2.2.2.jar, asm-commons-2.2.2.jar 파일을 classpath에 추가해 주어야 합니다.

top

TAG AOP, SpringAOP, xml

Write a comment.


Spring 사용하는 초간단 예제

AOP : 2007. 1. 9. 19:33


Spring Reference 6장을 보면서 거기 나오는 소스들을 연습하려는데...
어라? BeanFactory랑 ApplicationContext어떻게 썼지?
그래서 Spring을 사용하는 초간단 예제를 만들고 공부를 하기로 했습니다.

// Greeting.java

public interface Greeting {

       void sayHi();

}

// KoreanGreeting.java

public class KoreanGreeting implements Greeting{

       public void sayHi() {

             System.out.println("안녕하세요.");

       }

}

//applicationContext.xml

<?xml version="1.0" encoding="UTF-8"?>

<beans xmlns="http://www.springframework.org/schema/beans"

       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"

       xsi:schemaLocation="

http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.0.xsd">

       <bean id="korean" class="firstSpringApp.KoreanGreeting"/>

</beans>


//TestFirstSpringAPp.java

public class TestFirstSpringApp {

       public static void main(String[] args) {

             ApplicationContext ac = new ClassPathXmlApplicationContext(

                           new String[] { "firstSpringApp/applicationContext.xml" });

             Greeting greeting = (Greeting) ac.getBean("korean");

             greeting.sayHi();

       }

}



예제가 돌아가려면 프로젝트의 classpath에 spring.jar와 commons-logging.jar파일이 추가 되야합니다.
spring.jar파일은 '스프링 설치 폴더'/dist 안에 있고
commons-logging.jar파일은 '스프링 설치 폴더'/lib/jakarta-commons/ 에 있습니다.



top

Write a comment.


3. AspectJ 사용하는 초간단 AOP 예제

AOP : 2007. 1. 6. 16:45


앞에서 보았던 이클립스 플러긴을 잘~ 설치하신 뒤에(이클립스 메뉴를 사용한 설치 추천) 이클립스를 실행합니다.

소스 코드는 기본적으로 AJDT에서 제공해주는 데모 동영상을 참조했습니다.

먼저 이클립스에서 자바 프로젝트를 생성하고 다음과 같이 기본적인 클래스를 작성합니다.

public class Keesun {

       public static void main(String[] args) {

             new Keesun().say();

       }

       private void say() {

             System.out.println("keesun");

       }

}

현재 프로젝트 상태를 보면 다음과 같습니다.
사용자 삽입 이미지
프로젝트를 우클릭하고 나오는 메뉴에서 맨 끝에서 하나위를 보면 AspectJ Tools가 있습니다. 여기서 Convert To AsperctJ Project를 클릭합니다. 그럼 프로젝트가 다음과 같이 바뀝니다.
사용자 삽입 이미지
만약에 위처럼 바뀌지 않았다면 플러긴이 제대로 설치가 되지 않은 것입니다. 그럴땐 다시 설치를 하면 되겠죠 ^^; 저는 처음에 zip파일을 풀어서 설치 했다가 제대로 되지 않아서 엄청 시간을 소비 했답니다. 설치하는데 시간이 조금 걸리더라도 업데이트 사이트를 이용한 설치를 권장합니다.

이제는 Aspect를 만듭니다. 플러긴이 설치 됐다면 클래스를 만들던 아이콘 오른쪽 화살표를 누르면 A가 추가 된 것을 볼 수 있습니다. 그걸 이용해서 Aspect를 만들고 다음과 같이 코딩합니다.

public aspect Manner {

       pointcut callsay(): call (* Keesun.say (..));

 

       before(): callsay () {

             System.out.println("Welecome");

       }

       after(): callsay () {

             System.out.println("Good bye");

       }

}

이제 이전에 작성했던 Keesun 클래스를 실행합니다. 실행 할 때는 Shift + Alt + x , C 를 이용합니다. C가 Aspect Java Application 실행 단축키 입니다. 그런데 J 로 해도 되긴 되네요. :)

결과가 다음과 같이 나오면 정상입니다.
Welecome
keesun
Good bye

만약에 위와 같이 되지 않고.
Exception in thread "main" java.lang.NoClassDefFoundError: org/aspectj/lang/NoAspectBoundException
이런 메시지를 보게 되신 분들은 class path에 aspectjrt.jar 파일을 추가해주면 제대로 실행이 됩니다. 추가하는 방법은 Run 아이콘(녹색 동그라미에 화살표 그려져있는 아이콘)을 클릭하시고 다음 그림처럼 aspectjrt.jar를 추가해 주시면 됩니다.
사용자 삽입 이미지


top

Write a comment.


AspectJ 다운로드 & 이클립스 플러긴 설치

AOP : 2007. 1. 5. 21:43


AspectJ 다운로드 : http://www.eclipse.org/aspectj/downloads.php

AspectJ Development Tools(AJDT) 다운로드 : http://www.eclipse.org/ajdt/downloads/

사용자 삽입 이미지
AJDT 압축 파일을 보면 plugins와 features 디렉토리가 보입니다. 위 폴더는 각각 [eclipse가 설치된 폴더]/plugins 와 [eclipse가 설치된 폴더]/features 에 풀려야 합니다.

압축 파일 말고 Eclipse -> help -> Software Update - find and install 메뉴를 사용하실 분들은 다음의 주소를 이용하면 됩니다.
http://download.eclipse.org/tools/ajdt/32/update
top

  1. 한산 2007.01.06 07:44 PERM. MOD/DEL REPLY

    굿모닝! http://calamity84.oranc.co.kr/tt/88 댓글 갱신이용!! ㅎㅎㅎ

    Favicon of http://whiteship.tistory.com/ BlogIcon 기선 2007.01.06 13:14 PERM MOD/DEL

    ㅇㅇ귿모닝.

Write a comment.


2. Type of advice

AOP : 2007. 1. 5. 21:19


참조 : Spring Reference 6.1.1 AOP concepts

Before advice : join point 이 전에 실행이 되며 예외를 던지지 않는 이상 join point 이 후에 실행될 작업을 막을 방법이 없습니다.

After returning advice : join point가 정상적으로 완료된 후에 실행이 됩니다. 예외를 던지는 상황은 정상적인 상황에서 제외됩니다.

After throwing advice : 어떤 메소드가 예외를 던지면 실행이 됩니다.

Around advice : 메소드 호출과 같이 join point를 감싸는 Advice. 이 녀석은 advice 중에 가장 능력이 좋다. 메소드 호출 전과 후에 어떤 것을 실행할 수 있다. 또한 join point 이 후에 실행될 작업을 계속 수행할지 말지 정할 수 있다. 수행 하지 않을 때는 자신이 수행할 메소드 대신에 값을 반환하거나 예외를 던질 수 있다.

이 중에서 필요한 기능을 수행할 수 있는 가장 최소화된 능력을 발휘하는 Advice를 사용하는 것을 권장합니다. 예를 들어 어떤 메소드가 값을 반환한 이후 cache를 업데이트 하려고 할 때 Around advice를 사용할 수도 있겠지만 After returning advice를 사용합시다. 이렇게 가장 구체적인 Adivce 타입을 사용하는 것은 잠재적으로 발생할 에러를 방지 할 수 있습니다.

top

TAG advice, AOP

Write a comment.


1. AOP 용어 정리

AOP : 2006. 12. 29. 13:23


참고 : 객체지향을 넘어 관점지향으로 AOP

핵심 관심 : Major Concern (예 :: 게시판에 글쓰기, 글 보기, 글 삭제, 글 수정, ...)
횡단 관심 : Cross-Cutting Concern(예 :: 로깅, 인증, 예외처리, ...)

기존의 코드 : 핵심 관심과 횡당 관심이 결합되어 있는 형태. => 유지보수 어려움.(중복 발생, 지저분함, 생산성 저하, 재사용 힘듬, 변화 힘듬)
AOP 적용하는 코드 : 핵심 관심과 횡단 관심이 분리 되어 깔끔함.

Code : 핵심 관심을 구현한 것.
Advice : 횡단 관심을 구현한 것.
Joinpoint : Advice가 Code에 끼어 들 수 있는 순간들.
Pointcut : Joinpoint 중에 서 실제 Advice가 Code에 끼어드는 순간.
Aspect : Advice + Pointcut.
weaving : Code에 Aspect를 적용하는 과정.
사용자 삽입 이미지
출처 : 객체지향을 넘어 관점지향으로 AOP

AOP를 적용하지 않으면~
leakage of concern = 집중력 부족한 코드 = 유지보수 어려운 코드 = 안 좋은 코드

top

  1. Favicon of http://youngkun.info BlogIcon 영근 2007.01.05 16:36 PERM. MOD/DEL REPLY

    제가 대신 트랙백을.. 이렇게 정리하니깐 좋네요^^

    Favicon of http://whiteship.tistory.com/ BlogIcon 기선 2007.01.05 16:56 PERM MOD/DEL

    넵~ 헤헷 이걸 뭐라고 불러야 할까요. 흠..
    "트랙백 스터디"(?)

Write a comment.