2012-12-27 14 views
7

मेरे पास क्लाइंट नामक एक सार श्रेणी है। मैं एक एनोटेशन तक पहुंच कैसे प्राप्त कर सकता हूं जिसे बाल वर्ग पर कॉलिंग विधि पर घोषित किया गया था? इसे संभालने का सबसे अच्छा तरीका क्या है?जावा - एनोटेशन को परिभाषित और एक्सेस करना?

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

शायद आपने जो लिखा है उसके आधार पर कुछ ऐसा है। बार-बार प्रतिबिंब – radai

+0

@radai बहुत अच्छा विचार धन्यवाद – aryaxt

उत्तर

2

अपने उदाहरण के आधार पर इस कोड को अच्छी तरह से काम करता है: 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 
     } 
    } 

भी आप के साथ अपनी एनोटेशन चिह्नित करने की आवश्यकता:

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]; 

// यहाँ एक ध्यान ले @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(); 
    } 

} 

आउटपुट है: Cache.minute = 5

+0

प्रतिधारण क्या करता है से बचने के लिए केवल classname + methodname द्वारा परिणामों को कैश करें? और क्या यह प्रत्येक सिंक्रनाइज़ विधि के बजाय इसे 1 स्थान पर कार्यान्वित करना संभव है? धन्यवाद – aryaxt

+0

@aryaxt प्रतिधारण (RUNTIME) को रनटाइम में अपने एनोटैटन तक पहुंच प्रदान करने के लिए आवश्यक है (यह भी देखें: http://stackoverflow.com/questions/2286998/java-accessing-annotations-through-reflection)। मैं आपके प्रश्न के दूसरे भाग को * 1 स्थान * में कार्यान्वित करने के बारे में नहीं समझता हूं। यदि यह प्रतिधारण के बारे में है, तो आपको केवल कैश इंटरफ़ेस के साथ एनोटेट करने की आवश्यकता है। – Andremoniy

+0

मुझे प्रतिधारण की टिप्पणी करते समय यह त्रुटि मिली। इस स्थान के लिए एनोटेशन @ रीटेंशन की अनुमति नहीं है। – aryaxt

0

Andremoniy जवाब बिल्कुल सही है। एकमात्र चीज जो मैंने बदल दी वह जिस तरह से मैं स्टैक-ट्रेस में देख रहा था।

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(); 
    } 
संबंधित मुद्दे