2012-12-28 17 views
5

मुझे लगता है कि मुझे समझ में आया कि सीडीआई कैसे काम करता है और इसमें गहराई से गोता लगाने के लिए, मैं इसे वास्तविक दुनिया के उदाहरण के साथ उपयोग करने का प्रयास करना चाहता हूं। मैं एक चीज से फंस गया हूं जहां मुझे समझने के लिए आपकी मदद की ज़रूरत है। मैं इस संबंध में आपकी मदद की सराहना करता हूं।सीडीआई @ उत्पादक विधि कस्टम पैरामीटर ले सकते हैं?

मेरे पास जावा रिफ्लेक्शन एपीआई और एक्सएमएल कॉन्फ़िगरेशन का उपयोग करके अपना स्वयं का वर्कफ़्लो फ्रेमवर्क विकसित किया गया है जहां विशिष्ट प्रकार के "स्रोत" और "eventName" के आधार पर मैं उपयुक्त मॉड्यूल क्लास लोड करता हूं और उस पर "प्रक्रिया" विधि का आह्वान करता हूं। सब कुछ हमारी परियोजना में ठीक काम कर रहा है।

मैं CDI सुविधा के साथ बड़े उत्साहित थे और यह कार्यप्रवाह ढांचे के साथ की कोशिश जहां मैं मॉड्यूल वर्ग इंजेक्षन योजना बना रहा हूँ के बजाय प्रतिबिंब आदि का उपयोग कर उन्हें लोड देना चाहता था ...

बस आपको जानकारी देने के लिए, मैं कोशिश करूँगा चीजों को सरल रखने के लिए।

"संदेश.जावा" एक प्रकार का स्थानांतरण ऑब्जेक्ट है जिसमें "स्रोत" और "eventName" होता है, ताकि हम मॉड्यूल को उचित रूप से लोड कर सकें।

public class Message{ 
private String source; 
private String eventName; 
} 

मॉड्यूल विन्यास नीचे

<modules> 
<module> 
    <source>A</source> 
    <eventName>validate</eventName> 
    <moduleClass>ValidatorModule</moduleClass> 
</module> 
<module> 
    <source>B</source> 
    <eventName>generate</eventName> 
    <moduleClass>GeneratorModule</moduleClass> 
</module> 
</modules> 

ModuleLoader.java

public class ModuleLoader { 
public void loadAndProcess(Message message){ 
    String source=message.getSource(); 
    String eventName=message.getEventName(); 

    //Load Module based on above values. 

} 
} 

प्रश्न के रूप में

अब कर रहे हैं, अगर मैं एक ही लागू करने के लिए के माध्यम से CDI मुझे एक मॉड्यूल सुई (चाहते हैं मॉड्यूललोडर क्लास में), मैं @Produce विधि के साथ फैक्टरी क्लास लिख सकता हूं, जो ऐसा कर सकता है। लेकिन मेरा सवाल है,

ए) ईवेंट नाम और स्रोत के आधार पर लुकअप करने के लिए @Produce विधि को संदेश ऑब्जेक्ट कैसे पास कर सकता है?

क्या आप मुझे सुझाव दे सकते हैं?

अग्रिम धन्यवाद।

उत्तर

4

यह एक छोटा सा मुश्किल है क्योंकि सीडीआई आपके कस्टम समाधान (यदि मैं इसे सही ढंग से समझता हूं) के समान काम नहीं करता है। सीडीआई में बूट निर्भरता पर उन निर्भरताओं के लिए निर्भरताओं और संकल्पों की सभी सूची होनी चाहिए, जहां आपका समाधान लगता है जैसे यह रनटाइम पर सबकुछ पाता है जहां चीजें बदल सकती हैं। ऐसा कहा जा रहा है कि आप कुछ चीजें कोशिश कर सकते हैं।

आप उत्पादक विधि के पैरामीटर के रूप में InjectionPoint इंजेक्शन लगाने और सही ऑब्जेक्ट को वापस करने या सही प्रकार का निर्माण करने का प्रयास कर सकते हैं।

वहाँ भी यह कर और निर्भरता बनाने और विस्तार में उन सब को ऊपर तारों की अपनी खुद की एक्सटेंशन बना है (ProcessInjectionTarget, ProcessAnnotatedType पर एक नज़र डालें, और 'AfterBeanDiscovery` घटनाओं। ये twoquickstarts भी मदद मिल सकती कुछ विचार के लिए जा रहा हो।

+0

कृपया ध्यान दें कि इंजेक्शनपॉइंट चाल केवल तभी काम करती है जब आप एक निर्भर स्कॉप्ड बीन उत्पन्न करते हैं। Normalscoped सेम (सत्र स्कोप्ड, अनुप्रयोग स्कोप्ड, RequestScoped, आदि) के लिए यह _not_ काम करेगा क्योंकि आपके पास एकाधिक इंजेक्शन पॉइंट हैं और केवल एक ही नहीं। – struberg

3

मुझे लगता है कि आप निर्माता के बारे में गलत रास्ते पर जा रहे हैं। इसके बजाय एक पर्यवेक्षक का उपयोग करना बेहतर होगा, विशेष रूप से जो आपने वर्णित किया है उसके आधार पर।

मैं यह मान रहा हूं कि "संदेश" स्थानांतरण ऑब्जेक्ट का उपयोग एक प्रणाली व्यापक घटना की तरह किया जाता है जहां मूल रूप से आप ईवेंट को आग लगाते हैं और आप अपने एक्सएमएल ढांचे में परिभाषित कुछ हैंडलर को सही निर्धारित करने के लिए बनाए गए हैं घटना के लिए प्रबंधक, इसे तुरंत चालू करें (यदि आवश्यकता हो), और उसके बाद कक्षा को घटना को पास कर दें।


@ApplicationScoped 
public class MyMessageObserver { 

    public void handleMessageEvent(@Observes Message message) { 
     //Load Module based on above values and process the event 
    } 
} 

अब मान लेते हैं आप अपने मूल इंटरफ़ेस का उपयोग करने के लिए (मैं इसे की तरह लग रहा है लगता होगा) चाहते हैं: @Inject IMessageHandler handler;

:


public interface IMessageHandler { 
    public void handleMessage(final Message message); 
} 

@ApplicationScoped 
public class EventMessageHandler implements IMessageHandler { 

    @Inject 
    private Event<Message> messageEvent; 

    public void handleMessage(Message message) { 
     messageEvent.fire(message); 
    } 
} 

तो किसी भी विरासत कक्षा में आप इसे उपयोग करना चाहते हैं

यह आपको आपके द्वारा वर्णित सब कुछ करने की अनुमति देगा।

+1

एक और तरीका दिखाने के लिए धन्यवाद। यह दृष्टिकोण आशाजनक प्रतीत होता है। मुझे इसे एक मौका और देना होगा। – Raj

2

हो सकता है आप इस तरह somthing की जरूरत है:

  1. आप क्वालीफायर की जरूरत है। @ मॉड्यूल की तरह एनोटेशन, जो दो पैरामीटर स्रोत और घटना नाम लेगा; वे गैर योग्यता मान होना चाहिए। दस्तावेज़ देखें।

    @Produces 
    @Module 
    public Module makeAmodule(InjectionPoint ip) { 
        // load the module, take source and eventName from ip 
    } 
    
  2. इंजेक्षन उचित स्थान पर इस तरह:

  3. दूसरा आप एक निर्माता की जरूरत

    @Inject 
    @Module(source="A", eventName="validate") 
    Module modulA; 
    

है कि समाधान के साथ केवल एक ही मुद्दा है, उन मॉड्यूल निर्भर होना चाहिए दायरा, अन्यथा सिस्टम स्रोत और घटना नाम के समान मॉड्यूल के संबंध में इंजेक्ट करेगा। आप स्कोप का उपयोग करना चाहते हैं, तो आप स्रोत और घटनानाम योग्य मानकों बनाने के लिए और की जरूरत है:

  • CDI के लिए एक एक्सटेंशन बनाने के लिए, रजिस्टर प्रोग्राम के रूप में उत्पादकों
  • या प्रत्येक के लिए निर्माता विधि बनाने के लिए और स्रोत का हर संभव संयोजन और eventName (मुझे नहीं लगता कि यह अच्छा है)
संबंधित मुद्दे