2012-01-28 26 views
8

क्या सीडीआई कार्यक्रमों में टाइप भिन्नता का उपयोग करना संभव है? यहां मामला है:सीडीआई कार्यक्रमों की विरासत और सूचियों का उपयोग कैसे करें?

  • मान लीजिए मैं एक रूट घटना प्रकार है MyEvent और उपवर्ग DummyEvent
  • मेरा लक्ष्य घटनाओं की एक सूची एक दूरस्थ स्रोत List<? extends MyEvent> से प्राप्त कार्रवाई करने के लिए, DummyEvent उदाहरणों

युक्त मैं यह कैसे कर सकता हूँ?

यदि मैं प्रत्येक ईवेंट पर fire() पर कॉलिंग संग्रह के माध्यम से लूप करता हूं, तो यह @Observes MyEvent evt का आह्वान करेगा लेकिन @Observes DummyEvent evt विधियों का उपयोग नहीं करेगा।

** अद्यतन **

मुद्दा स्पष्ट करने के लिए एक नमूना कोड निर्मित: सूची से

https://github.com/jfaerman/jfaerman/blob/master/test-cdi/src/main/java/jfaerman/App.java

मैं घटना चाहते हैं दो बार, एक बार व्यक्तिगत रूप से सक्रिय करने की और एक समय ।

+0

आप कौन सी सीडीआई कार्यान्वयन का उपयोग कर रहे हैं? –

+0

जेबॉस में 7 –

उत्तर

3

यह घटना की BeanManager instad इंजेक्शन लगाने के काम करता है, के रूप में यह सर्वलेट द्वारा परीक्षण किया:

https://github.com/jfaerman/cdi-tests/blob/master/src/main/java/jfaerman/TestEventsServlet.java

वेल्ड मंच में इस सूत्र में जोज़ेफ़ HARTINGER द्वारा उत्तर दिया:

https://community.jboss.org/message/716185

+0

हमारे साथ साझा करने के लिए बहुत अच्छा +1 – dcernahoschi

1

एमएच मुझे यह नहीं मिला ... घटना का फायरिंग करने से पहले आपका वास्तविक कोड कैसा दिखता है? ASFAIK आप javax.enterprise.event.Event इंटरफ़ेस इंजेक्ट करते हैं और इसकी आग विधि को एक उदाहरण पास करते हैं, जिसके द्वारा बुलाए गए पर्यवेक्षक की घोषणा होती है। और यदि विरासत शामिल है, जैसे कि आपके मामले में, ऑब्जर्वर दोनों को बुलाया जाएगा, अगर आप डमीवेन्ट को आग लगाते हैं। यदि आप घटनाओं को आगे निर्दिष्ट करना चाहते हैं तो आप क्वालीफायर का उपयोग करेंगे।

@Inject @Any Event<DummyEvent> dummyEvent; 
... 
dummyEvent.fire(list.get(i)); 

/* संपादित करें */

"समस्या" कोड की निम्न पंक्ति है: जैसे ही आप घटना के प्रकार (MyEvent.class) specifiy रूप

weld.event().select(MyEvent.class).fire(evt); 

, वास्तविक घटना उदाहरण का प्रकार (evt) अब कोई फर्क नहीं पड़ता। क्वालिफायर के साथ अपनी कक्षा हिराची का विस्तार करना एक संभावना है। उदाहरण के लिए: आप सटीक निर्दिष्ट कर सकते हैं जब आप सिर्फ आधार वर्ग के लिए, तुम कहाँ itarate एक सूची के माध्यम से उपयोग कर सकते है अपने उदाहरण की तरह

public void observerChild(@Observes @ChildEvent.Child BaseEvent child){ 
     System.out.println("child with annotation event"); 
} 

अंत में,,:

@ChildEvent.Child 
public class ChildEvent extends BaseEvent{ 

    @Qualifier 
    @Retention(RetentionPolicy.RUNTIME) 
    @Target({ElementType.TYPE, ElementType.METHOD, ElementType.FIELD, ElementType.PARAMETER}) 
    public @interface Child{ 
    } 

    public void eventAction() { 
     System.out.println("child"); 
    }  
} 

उसके बाद आगे ऑब्जर्वर निर्दिष्ट ऐसे ही घटना फायरिंग से पहले/क्वालीफायर टाइप करें:

for (BaseEvent e : list){ 
    childEvent.select(e.getClass().getAnnotations()[0]).fire(e); 
} 

जैसा कि ऊपर उल्लेख, यदि आप एक सामान्य पर्यवेक्षक (नीचे दिखाया गया) है, यह प्रत्येक घटना के लिए बुलाया जाएगा।

public void observerBase(@Observes BaseEvent base){ 
    System.out.println("base event"); 
} 
+0

के रूप में वेल्ड कृपया कोड कोड जो मैंने अभी जोड़ा है, देखें, इस मुद्दे को थोड़ा और स्पष्ट करने की उम्मीद है। –

+0

उत्तर संपादित किया गया, शायद यह मदद करता है। –

+0

यह मदद करता है, लेकिन वहां मैं केवल प्रकारों का उपयोग कर एक समाधान ... पोस्टिंग के लिए धन्यवाद, चाल सीखा :) –