2012-03-12 29 views
5

का उपयोग करके एक विधि को ओवरराइड किया गया है या नहीं, मुझे प्रतिबिंब का उपयोग करके जेएसआर-330 एनोटेटेड कक्षाओं की निर्भरताओं को निर्धारित करने के लिए कुछ प्रसंस्करण करने की आवश्यकता है।जावा: प्रतिबिंब

मैं वसंत, गुइस या पिकोकॉन्टेनर जैसे सभी जेएसआर-330 अनुपालन आईओसी कंटेनर के बारे में पूरी तरह से अवगत हूं। हालांकि, मुझे जो चाहिए वह निर्भरताओं को हल करने और इंजेक्ट करने के लिए नहीं है, बल्कि उन्हें पहचानने के लिए है।

इसका मूल रूप से मतलब है कि मुझे जेएसआर-330 कार्यान्वयन को लागू करने की आवश्यकता है, कम से कम जब यह प्रतिबिंबित वर्ग "पार्सिंग" की बात आती है।

वहाँ जो मैं थोड़ा लागू करने के लिए परेशानी को खोजने JSR-330 विनिर्देश का एक हिस्सा है:

एक विधि @Inject साथ एनोटेट कि एक और तरीका @Inject साथ एनोटेट ओवरराइड करता है केवल इंजेक्शन प्रति एक बार इंजेक्शन दिया जाएगा प्रति उदाहरण अनुरोध। @Inject एनोटेशन वाला कोई तरीका @ इंजेक्ट के साथ एनोटेटेड विधि को ओवरराइड नहीं किया जाएगा।

इसका मतलब है कि उप-वर्ग अपने बेस क्लास के ऑटोवॉयरिंग अनुबंध को फिर से परिभाषित कर सकते हैं, साथ ही इंजेक्शन प्रवाह (पॉलिमॉर्फिज्म के माध्यम से) में हुक कर सकते हैं।

यहां मेरा प्रश्न आता है: कक्षा पदानुक्रम को देखते हुए, क्या यह जांचने का एक आसान तरीका है कि पदानुक्रम के कुछ हिस्सों में एक विधि पदानुक्रम के नीचे आगे बढ़ी है या नहीं?

सबसे आसान तरीका मैं मेरे मामले में यह करना होगा पदानुक्रम के पत्ते से प्रत्यावर्तन के साथ है:

private List<Method> getInjectableMethods(final Class<?> clazz) { 
    // recursive stop condition 
    if(clazz == null) { 
     return emptyList(); 
    } 

    // recursively get injectable methods from superclass 
    final List<Method> allInjectableMethods = newLinkedList(getInjectableMethods(clazz.getSuperclass())); 
    final List<Method> injectableMethods = newArrayList(); 

    // any overridden method will be present in the final list only if it is injectable in clazz 
    for (final Method method : clazz.getDeclaredMethods()) { 
     removeIf(allInjectableMethods, Methods.Predicates.overriddenBy(method)); 
     if (isInjectable(method)) { 
      injectableMethods.add(method); 
     } 
    } 
    allInjectableMethods.addAll(injectableMethods); 

    return allInjectableMethods; 
} 

overriddenBy अमरूद की तरह विधेय के रूप में, मैं की जाँच करेगा कि:

  • तरीकों वर्गों को परिभाषित एक isAssignableFrom संबंध
  • तरीकों नाम ही
  • तरीकों औपचारिक परम है में हैं eters एक ही हैं

परिणामस्वरूप जटिलता पदानुक्रम में विधियों की संख्या के संबंध में ओ (एन^2) है।

मैं सोच रहा था कि इसे प्राप्त करने के लिए कुछ आसान या अधिक कुशल तरीका था, या ऐसी कार्यक्षमता वाले किसी भी पुस्तकालय। मैंने गुवा और अपाचे कॉमन्स दोनों में असफल रूप से देखा है ...

+0

Google प्रतिबिंब शायद? http://code.google.com/p/reflections/ – biziclop

+0

मैंने javadocs को देखा और विधि ओवरराइड की जांच के लिए कुछ भी नहीं मिला। अच्छी लाइब्रेरी हालांकि, मैं इसे ध्यान में रखूंगा! – Eleaar

+0

सबसे खराब यह आपके एल्गोरिदम को आसान बना देगा।:) – biziclop

उत्तर

1

दुर्भाग्यवश, कक्षा ग्राफ केवल रूट दिशा में नेविगेट करने योग्य है - इसलिए कुछ क्लासलोडर को उपलब्ध सभी वर्गों को चेक करने के अलावा सभी व्युत्पन्न कक्षाओं को खोजने का कोई तरीका नहीं है। आईओसी कंटेनर इस समस्या नहीं है, क्योंकि वे हमेशा ठोस कार्यान्वयन पता

विरासत के पेड़ आमतौर पर IDEs द्वारा बनाया जाता है (यह विन्यास का हिस्सा है), लेकिन AFAIUK वे (आप कर सकते हैं सभी उपलब्ध स्रोतों/वर्गों से अधिक ब्राइट बल अनुक्रमण का उपयोग सुराग के लिए इंटेलिजे आईडीईए के सामुदायिक संपादन के स्रोतों में देखें)

संबंधित मुद्दे