2012-12-27 16 views
7

Mam klasę abstrakcyjną o nazwie Klient. W jaki sposób mogę uzyskać dostęp do adnotacji, która została zadeklarowana w metodzie potomnej w metodzie potomnej? Jaki jest najlepszy sposób, aby sobie z tym poradzić?Java - Definiowanie adnotacji i dostęp do nich?

public abstract class Client { 

    protected void synchronize() { 

     // How can I get the Annotation defined on inheriting class? 
     StackTraceElement[] stackTraceElements = Thread.currentThread().getStackTrace(); 
     StackTraceElement lastStackElement =  stackTraceElements[stackTraceElements.length-1] ; 
     Method m = this.getClass().getMethod(lastStackElement.getMethodName(),  String.class, int.class); 
     m.getAnnotation(Cache.class); 

     // synchronize data from server 
    } 

} 

.

public class OrderClient extends Client { 

    @Cache(minute = 5) 
    public void synchronizrWithCustomerId(String customerId) { 

     // So some stuff setup body and header 

     super.synchronize(); 
    } 

} 
+1

prawdopodobnie coś podobnego do tego, co właśnie zapisałeś. po prostu cache wyniki przez classname + methodname, aby uniknąć powtarzania refleksji – radai

+0

@radai bardzo dobry pomysł dzięki – aryaxt

Odpowiedz

2

Bazując na przykład ten kod działa dobrze:

public class TestS1 { 

    public abstract class Client { 

     protected void synchronize() throws NoSuchMethodException { 
      // How can I get the Annotation defined on inheriting class? 
      StackTraceElement[] stackTraceElements = Thread.currentThread().getStackTrace(); 
      StackTraceElement lastStackElement = stackTraceElements[2]; 

// brać uwagę tutaj: stackTraceElements[]

 Method m = this.getClass().getMethod(lastStackElement.getMethodName(), String.class); 
      Cache annotation = m.getAnnotation(Cache.class); 
      System.out.println("Cache.minute = " + annotation.minute()); 
      // synchronize data from server 
     } 
    } 

też trzeba zaznaczyć swoją adnotację z @Retention(RetentionPolicy.RUNTIME)

@Retention(RetentionPolicy.RUNTIME) 
    @interface Cache { 
     int minute(); 
    } 

    public class OrderClient extends Client { 
     @Cache(minute = 5) 
     public void synchronizrWithCustomerId(String customerId) throws NoSuchMethodException { 
      // So some stuff setup body and header 
      super.synchronize(); 
     } 
    } 

    public void doTest() throws NoSuchMethodException { 
     OrderClient oc = new OrderClient(); 
     oc.synchronizrWithCustomerId("blabla"); 
    } 

    public static void main(String[] args) throws NoSuchMethodException { 
     TestS1 t = new TestS1(); 
     t.doTest(); 
    } 

} 

Wyjście jest: Cache.minute = 5

+0

Co robi retencja? i czy możliwe jest zaimplementowanie go w 1 miejscu zamiast w każdej metodzie synchronizacji? dzięki – aryaxt

+0

@aryaxt Retention (RUNTIME) jest potrzebny, aby zapewnić dostęp do twoich annotaitons w Runtime (zobacz także: http://stackoverflow.com/questions/2286998/java-accessing-annotations-through-reflection). Nie rozumiem drugiej części twojego pytania o * wprowadzenie jej w 1 miejsce *. Jeśli chodzi o Retention, musisz więc dodać do niego tylko interfejs Cache. – Andremoniy

+0

Mam ten błąd podczas retuszu uwagi. Adnotacja @Rekcja jest niedozwolona dla tej lokalizacji. – aryaxt

0

Andremoniy Odpowiedź jest absolutnie poprawne. Jedyne, co zmieniłem, to sposób, w jaki sprawdzam ślad stosu.

Cache cache = null; 

    try { 
     StackTraceElement[] stackTraceElements = Thread.currentThread().getStackTrace(); 

     for (StackTraceElement element : stackTraceElements) { 
      if (this.getClass().getName().equals(element.getClassName())) { 
       Method method = this.getClass().getMethod(element.getMethodName(), String.class); 
       cache = method.getAnnotation(Cache.class); 
       break; 
      } 
     } 
    } catch (NoSuchMethodException e) { 
     e.printStackTrace(); 
    } 
Powiązane problemy