2011-08-24 4 views
12

인터페이스 메소드를 주석으로 대체하는 메소드 실행에 적용되는 aspectj 포인트 컷을 작성하려면 어떻게해야합니까? 예를 들어 : B.method()이 주석 자체를 수행하는 경우@AspectJ 주석이있는 인터페이스 메소드를 오버라이드하는 메소드의 포인트 컷

interface A { 
    @MyAnnotation void method(); 
} 
class B implements A { 
    void method(); 
} 

포인트 컷 execution(@MyAnnotation * *.*(..))에만 일치 않습니다. 이것을 할 또 다른 방법이 있습니까?

답변

10

Nicholas가 지적했듯이 AspectJ에서는 불가능합니다. 여기서 이상 (http://www.eclipse.org/aspectj/doc/released/adk15notebook/annotations-pointcuts-and-advice.html 섹션 주석 상속 포인트 컷 매칭 찍은)이 불가능 이유 증거 : 자바 5 스펙에 따르면

가 아닌 타입 주석 상속되지 및 유형에 주석 전용 그들이 @Inherited 메타 - 어노테이션을 가지고 있다면 상속된다. 수정 자 (visibility modifiers, annotations 및 throws 절)에 대한 조인 포인트 일치는 조인 포인트의 주제에 기반하므로 (예제에서 b.method()가 될 것임) c2.aMethod에 대한 호출이 일치하지 않습니다. 메서드가 실제로 호출 됨).

동일한 문제로 어려움을 겪었으므로 이러한 방법에 대한 pointcuts를 작성할 수있는 작은 방법/라이브러리를 작성했습니다.여기 당신의 예를 들어 어떻게 작동하는지입니다 :

myAnnotationIsExecuted(): execution(public * *.*(..)) && 
      if(implementsAnnotation("@MyAnnotation()", thisJoinPoint)); 

또는

myAnnotationIsExecuted(): execution(public * A+.*(..)) && 
      if(implementsAnnotation("@MyAnnotation()", thisJoinPoint)); 

implementsAnnotation(String,JoinPoint) 라이브러리에서 오는 방법; 구현 된 메소드가 지정된 주석을 포함하는지 여부를 확인하는 기본 메소드.

방법/라이브러리에 대한

더 많은 정보를 찾을 수 있습니다 here.

3

가가 (원래 대답을 참조) 난 당신이 구현하는 클래스의 각 메소드에 주석을 추가 할 필요가 있다는 말을 봄에서 수행 할 수 없음을 표시하기 때문에 업데이트. 이 작업을 수행하는 분명한 방법이 있지만 더 직접적인 방법을 찾고 있다면 직접 작성해야합니다.

가정용 포스트 프로세서가 특정 주석을 찾을 수 있다고 상상해보십시오. @ApplyThisAnnotationToAllWhoInheritMe을 말하면됩니다. 일단이 주석을 찾으면, 상속 멤버에 대한 소스 코드를 스캔하고 컴파일이 일어나기 전에 필요한 곳에서 요청 된 주석을 추가합니다.

그렇다면 Spring AOP를 사용하는 경우 implementers 메소드에 있어야하는 것처럼 보입니다. 이 클래스가 도움이되지 않으면, Spring AOP 툴을 직접 작성해야 할 수도 있습니다.

Spring 3.0 Documentation에서

원래 답변 :

AspectJ를이 인터페이스의 주석이 상속되지 자바의 규칙을 따른다.

나는 날이 글로벌 규칙입니다 생각하게 7.8 Using AspectJ with Spring applications의 일부입니다 섹션 7.8.2 Other Spring aspects for AspectJ에서이 비트를 발견했다.

+0

감사합니다; 내 포인트 컷이 작동하지 않는 이유가 설명되어 있습니다. 그러나, 나는 작품을 찾고 있어요. :-) –

+0

@hstoerr : 질문을 편집 한 후 내 대답을 편집했습니다. 아직 받아 들일 수 없다면 알려주세요. –

+1

봄의 문서는 실제로 내가 원하는 것과 일치하는 것이 불가능하다는 것을 실제로 말하지 않는다 - 내가 시도한 간단한 접근법이 작동하지 않는다. 내가 생각할 수없는 Aspectj에서 할 수있는 이상한 일이있을 수 있습니다. 그래서 나는 아직도 희망하고있다. :-) –

2
//introducing empty marker interface 
declare parents : hasmethod(@MyAnnotation * *(..)) implements TrackedParentMarker; 

public pointcut p1() : execution(* TrackedParentMarker+.*(..)); 

또한 -XhasMember 컴파일러 플래그를 설정해야합니다.

+0

불행히도 그렇게하지는 않습니다. 어노테이션을 전달하는 적어도 하나의 메소드가있는 인터페이스를 구현하는 모든 클래스의 모든 메소드에 적용됩니다. 그러나 그것은 해당 마커를 사용하여 인터페이스 메소드를 구현하는 하나의 메소드에만 적용해야합니다. 또는 적어도 AspectJ에서 말할 수있는 경우 표시된 인터페이스 메소드와 이름이 같은 메소드. –