यहां कई मुद्दे हैं।
- पूरे एप्लिकेशन में वांछित कार्यान्वयन को बदलने का सबसे अच्छा तरीका क्या है?
@Alternatives
में देखें।
- क्या मुझे प्रत्येक कार्यान्वयन के लिए योग्यता की आवश्यकता है? नहीं, this एक लंबा और विस्तृत स्पष्टीकरण के लिए उत्तर देखें।
- क्या मुझे यह निर्धारित करने के लिए निर्माता का उपयोग करना चाहिए कि कौन सा कार्यान्वयन इंजेक्शन दिया गया है? वह समाधान हो सकता है जो आप चाहते हैं, लेकिन मुझे शक है। निर्माता आमतौर पर कुछ प्रकार के प्रारंभिक प्रदर्शन करने के लिए उपयोग किए जाते हैं जिन्हें कन्स्ट्रक्टर/
@PostConstruct
में नहीं किया जा सकता है। इंजेक्शन प्वाइंट का निरीक्षण करने और इंजेक्ट करने के बारे में रनटाइम निर्णय लेने के लिए आप इसका इस्तेमाल भी कर सकते हैं। कुछ सुराग के लिए लिंक 2 देखें।
क्या यह समाधान सही है? यह काम करेगा, लेकिन कार्यान्वयन को बदलने के लिए आपको अभी भी कोड के साथ गड़बड़ करनी होगी, इसलिए पहले 1. पर विचार करें। @Calculator Calculator
भी अत्यधिक अनावश्यक लगता है। दोबारा, लिंक 2 देखें।
@ApplicationScoped
public class CalculatorFctory implements Serializable {
private Calculator calc;
@Produces @Calculator Calculator getCalculator() {
return new Calculator();
}
}
अद्यतन:
CDI क्वालिफायर निर्भरता समाधान के लिए इसके अलावा प्रकार करने के लिए उपयोग करता है। दूसरे शब्दों में, जब तक केवल एक ही प्रकार होता है जो इंजेक्शन बिंदु के प्रकार से मेल खाता है, अकेले प्रकार पर्याप्त हैं और क्वालिफायर की आवश्यकता नहीं है। क्वालिफायर असंबद्धता के लिए हैं जब अकेले प्रकार पर्याप्त नहीं हैं।
उदाहरण के लिए:
@Inject ImplOne bean;
या
@Inject ImplTwo bean;
है यही कारण है कि मैं कहता हूँ @Calculator Calculator
:
public class ImplOne implements MyInterface {
...
}
public class ImplTwo implements MyInterface {
...
}
या तो कार्यान्वयन इंजेक्षन करने में सक्षम होने के लिए, यदि आप किसी भी क्वालिफायर की जरूरत नहीं है अनावश्यक है यदि आप प्रत्येक कार्यान्वयन के लिए क्वालीफायर परिभाषित करते हैं, तो आप अधिक लाभ नहीं उठा रहे हैं, साथ ही साथ इस प्रकार का उपयोग भी कर सकते हैं। कहो, दो क्वालिफायर @QualOne
और @QualTwo
:
@Inject @QualOne ImplOne bean;
और
@Inject @QualTwo ImplTwo bean;
उदाहरण सीधे ऊपर पिछले उदाहरण कोई असंतुष्ट अस्पष्टता पहले से ही अस्तित्व में है के बाद से कुछ भी हासिल नहीं होता है।
@Inject @QualOne MyInterface bean; // to inject TypeOne
और
@Inject @QualTwo MyInterface bean; // to inject TypeTwo
@Produces हालांकि ओ पी का उपयोग नहीं किया जाना चाहिए: जहां विशेष रूप से कार्यान्वयन प्रकार के लिए पहुँच नहीं है
ज़रूर, तुम मामलों के लिए ऐसा कर सकते हैं जब वह कैलिफोर्निया कार्यान्वयन सीडीआई प्रबंधित करने के लिए चाहता है।
@Avinash सिंह - CDI, कुछ भी वे लौट के रूप में रूप में अच्छी तरह @Produces
का प्रबंधन करता है जब तक कि यह CDI कि प्रणाली को बुलाती है। यदि आप कृपया this section of the spec देखें। यह लौटने `शामिल @ ... scoped सेम जो निर्भरता इंजेक्शन, जीवन-चक्र कॉलबैक का समर्थन करेंगे, आदि
मैं यहाँ कुछ विवरण अनदेखी की है, तो विचार करना दो निम्नलिखित:
public class SomeProducer {
@Inject ImplOne implOne;
@Inject ImplTwo implTwo;
@Inject ImplThree implThree;
@Produces
public MyInterface get() {
if (conditionOne()) {
return implOne;
} else if (conditionTwo()) {
return implTwo;
} else {
return implThree;
}
}
}
और
public class SomeProducer {
@Produces
public MyInterface get() {
if (conditionOne()) {
return new ImplOne();
} else if (conditionTwo()) {
return new ImplTwo();
} else {
return new ImplThree;
}
}
}
फिर, पहले उदाहरण में, सीडीआई उत्पादक से वापस आने वाले जीवन चक्र (यानी @PostConstruct
और @Inject
समर्थन) का प्रबंधन करेगा, लेकिन दूसरे में यह नहीं होगा।
मूल प्रश्न पर वापस जाएं - स्रोत को संशोधित किए बिना कार्यान्वयन के बीच स्विच करने का सबसे अच्छा तरीका क्या है? धारणा यह है कि आप परिवर्तन को व्यापक रूप से आवेदन करना चाहते हैं।
@Default
public class ImplOne implements MyInterface {
...
}
@Alternative
public class ImplTwo implements MyInterface {
...
}
@Alternative
public class ImplThree implements MyInterface {
...
}
फिर, किसी भी @Inject MyInterface instance
के लिए किसी भी, ImplOne
इंजेक्ट किया जाएगा, जब तक
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://java.sun.com/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/beans_1_0.xsd">
<alternatives>
<class>ImplTwo</class>
</alternatives>
</beans>
निर्दिष्ट किया जाता है, जिसमें मामले ImplTwo
हर जगह इंजेक्शन दिया जाएगा।
इसके अलावा अद्यतन
वहाँ वास्तव में इस तरह के EJBs और वेब सेवाओं के रूप में जावा ईई वातावरण में चीजें हैं जो CDI द्वारा प्रबंधित नहीं कर रहे हैं, कर रहे हैं।
आप एक सीडीआई प्रबंधित बीन में एक वेब सेवा कैसे इंजेक्ट करेंगे? यह वास्तव में आसान है:
@WebServiceRef(lookup="java:app/service/PaymentService")
PaymentService paymentService;
यही है, वहां आपके पास भुगतान सेवा का वैध संदर्भ होगा जो सीडीआई के बाहर प्रबंधित किया जाता है।
लेकिन, यदि आप हर जगह पूर्ण @WebServiceRef(lookup="java:app/service/PaymentService")
का उपयोग नहीं करना चाहते हैं तो आपको इसकी आवश्यकता है? क्या होगा यदि आप केवल इसे टाइप करके इंजेक्ट करना चाहते हैं? तो फिर तुम इस कहीं कार्य करें:
@Produces @WebServiceRef(lookup="java:app/service/PaymentService")
PaymentService paymentService;
और किसी भी CDI सेम है कि भुगतान सेवा आप बस @Inject
इसे इस तरह CDI का उपयोग कर सकते हैं के लिए एक संदर्भ की जरूरत में:
@Inject PaymentService paymentService;
ध्यान दें कि निर्माता क्षेत्र को परिभाषित करने से पहले , PaymentService
इंजेक्शन सीडीआई मार्ग इंजेक्शन के लिए उपलब्ध नहीं होगा। लेकिन यह हमेशा पुराना तरीका उपलब्ध है। इसके अलावा, किसी भी मामले में वेब सेवा सीडीआई द्वारा प्रबंधित नहीं की जाती है लेकिन निर्माता क्षेत्र को परिभाषित करने से सीडीआई मार्ग इंजेक्शन के लिए बस उस वेब सेवा संदर्भ उपलब्ध कराया जाता है।
कृपया अपनी टिप्पणी के अनुसार मेरा अपडेट देखें। इसके अलावा, निर्माता और वे जो भी लौटाते हैं उन्हें सीडीआई द्वारा प्रबंधित किया जाता है ... – rdcrng
यदि आप इसे स्वयं कॉल करने जा रहे हैं तो '@ प्रोड्यूस' के साथ कुछ भी टिप्पणी करने का कोई कारण नहीं है। – rdcrng
आप इस सेवा को सीडीआई बीन में कैसे इंजेक्ट करेंगे? हम '@Produces @myservice @WebServiceRef (lookup =" जावा: ऐप/सेवा/भुगतान सेवा ") {} @ इंजेक्ट @ myservice MyWebService का उपयोग करेंगे; 'इस मामले में कंटेनर MyWebServiceImpl जीवन चक्र का प्रबंधन नहीं करता है, यह केवल इसे –