2010-07-12 15 views
5

में एक सामान्य इंटरफ़ेस को लागू करने वाले सभी बीन्स प्राप्त करें वसंत में एक विशिष्ट सामान्य इंटरफ़ेस (उदा। फ़िल्टर <TestEvent>) को लागू करने वाले सभी बीन्स का संदर्भ कैसे प्राप्त करें?स्प्रिंग

public interface Filter<T extends Event> { 

    boolean approve(T event); 

} 


public class TestEventFilter implements Filter<TestEvent> { 

    public boolean approve(TestEvent event){ 
     return false; 
    } 

} 

public class EventHandler{ 
    private ApplicationContext context; 

    public void Eventhandler(DomainEvent event) { 
     // I want to do something like following, but this is not valid code 
     Map<String, Filter> filters = context.getBeansOfType(Filter<event.getClass()>.class); 
     for(Filter filter: filters.values()){ 
      if (!filter.approve(event)) { 
       return; // abort if a filter does not approve the event 
      } 
     } 
     //... 
    } 

} 

मेरे वर्तमान कार्यान्वयन प्रतिबिंब का उपयोग करता है निर्धारित करने के लिए filter.approve यह कॉल करने से पहले घटना को स्वीकार करता है तो:

यह मैं क्या लाइनों की एक न्यूनतम संख्या के साथ हासिल करना चाहते हैं। ईजी।

 Map<String, Filter> filters = context.getBeansOfType(Filter.class); 
     for(Filter filter: filters.values()){ 
      if (doesFilterAcceptEventAsArgument(filter, event)) { 
       if (!filter.approve(event)) { 
        return; // abort if a filter does not approve the event 
       } 
      } 
     } 

कहाँ doesFilterAcceptEventAsArgument सभी बदसूरत काम है कि मैं चाहते हैं से दूर होने के लिए करना चाहते है। कोई सुझाव?

उत्तर

2

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

सामान्यतः, रनटाइम पर जेनेरिक जानकारी का उपयोग करना संभवतः मुश्किल है। इस मामले में आप सामान्य सीमाएं प्राप्त कर सकते हैं, लेकिन मैन्युअल रूप से जांचने के लिए एनोटेशन के रूप में इसे उपयोग करने के अलावा, आपको वास्तव में सामान्य परिभाषा से अधिक लाभ नहीं मिल रहा है।

किसी भी मामले में, आपको कुछ लौटाए गए ऑब्जेक्ट पर चेक की जांच करनी होगी, इसलिए आपका मूल कोड ब्लॉक काम नहीं करेगा; doesFilterAcceptEventAsArgument के कार्यान्वयन में एकमात्र भिन्नता है। क्लासिक OO तरह से, (फ़िल्टर इंटरफ़ेस करने के लिए और जोड़ने के बाद) के रूप में दो तरीकों के साथ एक सार सुपर क्लास जोड़ने के लिए होगा:

protected abstract Class<E> getEventClass(); 

public boolean acceptsEvent(Object event) // or an appropriate class for event 
{ 
    return getEventClass().isAssignableFrom(event.getClass()); 
} 

यह एक दर्द की तरह है, क्योंकि आप तुच्छ को लागू करना होगा उपयुक्त वर्ग शाब्दिक लौटने के लिए प्रत्येक कार्यान्वयन में getEventClass() विधियां, लेकिन यह जेनेरिक की एक ज्ञात सीमा है। भाषा की सीमाओं के भीतर, यह संभवतः सबसे साफ दृष्टिकोण है।

लेकिन यह आपके लिए लायक है इसके लिए ठीक है।

Map<String, Filter> filters = context.getBeansOfType(Filter.class); 
    for(Filter filter: filters.values()){ 
     try { 
      if (!filter.approve(event)) { 
       return; // abort if a filter does not approve the event. 
      } 
     } catch (ClassCastException ignored){ } 
    } 

और यह काफी अच्छी तरह से प्रोटोटाइप के लिए काम किया:

+0

धन्यवाद, जैसा कि मैंने संदेह किया था। –

4

बस संदर्भ के लिए, सबसे आसान समाधान मैं का निर्माण कर सकता है यह किया गया था।