2012-08-26 4 views
4

AspectJ를 사용하여 웜홀 패턴을 구현 한 예를 찾고있다. Guice AOP가이를 구현할 수있는 능력이 있다면 관심이있다.AspectJ를 사용하여 웜홀 패턴 구현하기

웜 홀은 본질적으로는 예를 들어 통화 흐름에 따라 추가 매개 변수를 전달할 수 있습니다 :

// say we have 
class foo { 
    public int m0 int a, int b) { 
    return m1(a,b); 
    } 

    public int m1 int a, int b) { 
    return m2(a,b); 
    } 

    public int m2 int a, int b) { 
    return a+b; 
    } 
} 
// and I wanted in a non-invasive manner to pass a third parameter of type 
class context { 
    String userName; 
    long timeCalled; 
    String path; 
} 
// I could use an advise to say print the context information 
// to trace what was going on without mucking up my method signatures 

나는이 램니 바스 라 다드 액션에서 그의 책 AspectJ를 그러한 예를 가지고 있다고 생각합니다.

미리 감사드립니다.

답변

4

실제로 예가 AspectJ in Action입니다. table of contents을 보면 12.2 절이 여러분이 찾고있는 것임을 알 수 있습니다. 책을 사는 것이 좋은 생각 일 것입니다. 나는 그것을 따뜻하게 추천 할 수있다. 단지 책의 & 붙여 넣기 부분을 복사하는 것이 괜찮은지 나는 확실하지 않다 때문에, 여기 템플릿을 인용 단지 것보다 구체적인 예와 함께 TheServerSide.com에 오래된 article by Laddad을가

public aspect WormholeAspect { 
    pointcut callerSpace(<caller context>) : 
     <caller pointcut>; 

    pointcut calleeSpace(<callee context>) : 
     <callee pointcut>; 

    pointcut wormhole(<caller context>, <callee context>) : 
     cflow(callerSpace(<caller context>)) && 
     calleeSpace(<callee context>); 

    // advice to wormhole 
    before(<caller context>, <callee context>) : 
     wormhole(<caller context>, <callee context>) 
    { 
      ... advice body 
    } 
} 

. 그것은 책과 같은 것이 아니라 비슷합니다.

당신이 볼 수 있듯이, 당신은 cflow() pointcut을 가지고 있기 때문에 AspectJ에서 쉽게 할 수있다. Guice를 한번도 사용한 적이 없지만 AOP introduction 페이지에는 해당 구현이 AOP Alliance 사양의 일부라고 언급되어 있습니다. AOP Alliance API을 보면, cflow() 포인트 컷처럼 보이지 않으며, 모든 것은 생성자 & 메소드 호출과 필드 접근을 둘러싼 것입니다.

그래서 모든 레이어를 통해 매개 변수를 전달하지 않으려면 Spring (AspectJ없이) 또는 Guice에서 무엇을 할 수 있습니까? 분명한 해결책은 호출자가 선언하고 관리 (할당, 또한 소거) 된 변수이며 호출 수신자가 액세스하는 ThreadLocal 변수입니다. 이것은 좋지 않습니다. API를 부 풀리지 않으려면 해결 방법 일뿐입니다. 그러나 발신자와 수신자 모두 공유하고 싶은 것을 공통적으로 이해하고 있어야합니다. 그런 종류의 구현은 패턴보다는 반 패턴입니다. 가능하다면, AspectJ를 사용하여 하나의 모듈 (aspect)에서 다루어야 할 문제를 캡슐화하면서 깨끗하고 모듈화 된 방식으로 이것을 해결한다.

+0

많은 감사가 @kriegaex을 ... 나는 책 – user1172468

1

웜홀 패턴을 사용하지 마십시오. 실제로 필요한 경우에만 AOP를 사용하고, 그렇지 않으면 그대로 두십시오.

웜홀 패턴의 단점은 많은 레이어를 건너 뛰는 것입니다 ... 그게 정말로 원하는 것입니까? :)

Grtz,

크리스토프

+0

H 데리러 갈게 나는 웜홀 패턴을 사용하여 메소드 서명을 깨끗하게 유지하고 싶다. 예를 들어, 순전히 구현의 부작용이며 사용중인 유스 케이스와 관련이 거의없는 콜 흐름을 따라 많은 컨텍스트 및 기타 정보를 전달하려는 경우. – user1172468

1

간단한 예.당신이 상황대상을 상상하는 것은 어떻게 든 컨텍스트의 상태에 따라 기능을 제공 객체 :

class T { 
    public void foo() { 
     System.out.println("T.foo()"); 
    } 
} 

class Context { 
    public boolean isValid = true; 
    public void doStuff() { 
     T t = new T(); 
     t.foo(); 
    } 
} 

public class Main { 
    public static void main(String[] args) { 
     Context c = new Context(); 
     c.doStuff(); 
    } 
} 

Context의 인스턴스를 확보 할 목적은 T의 예를 경우에만에 foo()를 호출 할 수 있습니다 회원 isValid는 다음과 같은 방법으로 볼 수 있었다 true으로 설정됩니다

public aspect ContextStateValidation { 

    pointcut MyContext(Context c) : 
     execution(* Context.*()) && this(c); 

    pointcut FooCalls(T t) : 
     call(* T.foo()) && target(t); 

    pointcut FooCallsInMyContext(Context c, T t) : 
     cflow(MyContext(c)) && FooCalls(t); 

    void around(Context c, T t) : FooCallsInMyContext(c, t) { 
     if (c.isValid) 
      proceed(c, t); 
    } 
} 
관련 문제