2011-08-24 35 views
12

Làm cách nào tôi có thể viết một pointj khía cạnh áp dụng cho các phương thức thực thi phương thức ghi đè phương thức giao diện bằng chú thích? Ví dụ:@AspectJ pointcut cho các phương pháp ghi đè phương thức giao diện bằng chú thích

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

Phím tắt execution(@MyAnnotation * *.*(..)) chỉ phù hợp nếu B.method() mang chú thích. Có một cách khác để làm điều này?

Trả lời

10

Như Nicholas đã chỉ ra, điều này là không thể trong AspectJ. Đây là bằng chứng nữa về việc tại sao nó không thể (lấy từ http://www.eclipse.org/aspectj/doc/released/adk15notebook/annotations-pointcuts-and-advice.html phần Chú Thừa kế và phù hợp với pointcut):

Theo đặc tả Java 5, không loại chú thích không được thừa kế, và chú thích trên các loại chỉ được kế thừa nếu chúng có chú thích meta @Inherited. Cuộc gọi đến c2.aMethod (đó sẽ là b.method() trong ví dụ của bạn) không khớp vì kết hợp điểm nối cho các công cụ sửa đổi (các điều chỉnh hiển thị, các chú thích và mệnh đề ném) được dựa trên chủ đề của điểm nối (phương thức thực sự được gọi).

Có vấn đề tương tự, tôi đã viết một phương pháp/thư viện nhỏ cho phép bạn viết các phím tắt cho các phương pháp như vậy.Sau đây là cách nó sẽ làm việc ví dụ của bạn:

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

HOẶC

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

Phương pháp implementsAnnotation(String,JoinPoint) đến từ thư viện; một phương thức cơ bản để kiểm tra xem các phương thức đã triển khai có chứa chú thích được chỉ định hay không.

Thông tin thêm về phương pháp/thư viện có thể được tìm thấy here.

3

Cập nhật

Kể từ khi nó xuất hiện rằng nó không thể được thực hiện trong mùa xuân (xem câu trả lời ban đầu) Tôi sẽ nói rằng bạn cần phải thêm chú thích cho từng phương pháp trên lớp thực hiện. Có một cách rõ ràng để làm điều này, nhưng tôi cho rằng nếu bạn đang tìm kiếm một cách tự động hơn, bạn sẽ cần phải viết một mình.

Tôi có thể tưởng tượng một số loại trình xử lý hậu kỳ phát triển tại nhà sẽ tìm kiếm một chú thích cụ thể, cho phép nói @ApplyThisAnnotationToAllWhoInheritMe. Một khi nó tìm thấy chú thích này, nó sẽ quét mã nguồn để kế thừa các thành viên và thêm chú thích được yêu cầu khi cần thiết trước khi biên dịch xảy ra.

Bất kể, nếu bạn đang sử dụng Spring AOP để làm điều này, có vẻ như nó cần phải được trên phương pháp triển khai. Nếu các lớp bạn đang hy vọng điều này sẽ giúp bạn không thể kiểm soát được, bạn có thể phải viết công cụ Spring AOP của riêng bạn.

gốc trả lời

Từ Spring 3.0 Documentation:

AspectJ sau quy tắc của Java rằng chú thích trên giao diện không được thừa kế.

Tôi tìm thấy bit này trong phần 7.8.2 Other Spring aspects for AspectJ, là một phần của 7.8 Using AspectJ with Spring applications, khiến tôi nghĩ đây là quy tắc toàn cầu.

+0

Cảm ơn; điều đó giải thích tại sao con trỏ của tôi không hoạt động. Tuy nhiên, tôi đang tìm kiếm một công trình. :-) –

+0

@hstoerr: Sau khi bạn chỉnh sửa câu hỏi của mình, tôi đã chỉnh sửa câu trả lời của mình. Hãy cho tôi biết nếu nó vẫn không thể chấp nhận được. –

+1

Tài liệu hướng dẫn mùa xuân không thực sự nói rằng không thể khớp với thứ gì đó giống như những gì tôi muốn - chỉ là cách tiếp cận đơn giản mà tôi đã thử không hoạt động. Có thể có một số điều kỳ lạ mà người ta có thể làm trong Aspectj mà tôi không thể nghĩ ra. Vì vậy, tôi vẫn hy vọng. :-) –

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

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

Bạn cũng nên bật cờ trình biên dịch –XhasMember.

+0

Thật không may là không hoàn toàn làm điều đó. Nó áp dụng cho mọi phương thức của tất cả các lớp thực hiện một giao diện có ít nhất một phương thức mang chú thích. Nhưng nó chỉ nên áp dụng cho một phương pháp thực hiện phương thức giao diện với điểm đánh dấu đó. Hoặc ít nhất là các phương thức có cùng tên với phương thức giao diện được đánh dấu, nếu có thể nói trong AspectJ. –

Các vấn đề liên quan