EJB 3.1 और CDI का उपयोग कहां करें?


120

मैं एक जावा ईई आधारित उत्पाद बना रहा हूं जिसमें मैं ग्लासफिश 3 और ईजेबी 3.1 का उपयोग कर रहा हूं ।

मेरे आवेदन में सत्र सेम , एक अनुसूचक है और वेब सेवाओं का उपयोग करता है। मुझे हाल ही में Apache TomEE के बारे में पता चला , जो Contexts और Dependency Injection (CDI) को सपोर्ट करता है । ग्लासफिश कंटेनर भी सीडीआई का समर्थन करता है।

क्या मैं सत्र बीन्स को बदल सकता हूं जहां मुझे किसी भी सुविधा की आवश्यकता नहीं है जो सीडीआई पहले से ही प्रदान नहीं करता है? और अगर है, तो मुझे क्या लाभ मिल सकते हैं?

जवाबों:


408

हां, आप सीडीआई और ईजेबी दोनों को स्वतंत्र रूप से मिला सकते हैं और कुछ शानदार परिणाम प्राप्त कर सकते हैं। ऐसा लगता है कि आप उपयोग कर रहे हैं @WebServiceऔर @Schedule, जो मिश्रण में ईजेबी जोड़ने के लिए अच्छे कारण हैं।

वहाँ बहुत भ्रम की स्थिति है, इसलिए यहां ईजेबी और सीडीआई पर कुछ सामान्य जानकारी है क्योंकि वे एक-दूसरे से संबंधित हैं।

EJB> = सीडीआई

ध्यान दें कि EJB हैं CDI सेम और इसलिए CDI के सभी लाभों की है। रिवर्स सच नहीं है (अभी तक)। तो निश्चित रूप से "ईजेबी बनाम सीडीआई" सोचने की आदत में मत पड़ो क्योंकि तर्क वास्तव में "ईजेबी + सीडीआई बनाम सीडीआई" में अनुवाद करता है, जो एक अजीब समीकरण है।

जावा ईई के भविष्य के संस्करणों में हम उन्हें संरेखित करना जारी रखेंगे। क्या साधन संरेखित, लोग क्या वे पहले से ही कर सकते हैं करने की अनुमति है, बस बिना @Stateful, @Statelessया @Singletonशीर्ष पर एनोटेशन।

कार्यान्वयन की शर्तों में EJB और CDI

अंत में, EJB और CDI सम्‍मिलित घटकों के समान मौलिक डिजाइन को साझा करते हैं। जब आपको EJB या CDI बीन का संदर्भ मिलता है, तो यह असली बीन नहीं है। बल्कि आपके द्वारा दी गई वस्तु एक नकली (एक प्रॉक्सी) है। जब आप इस नकली वस्तु पर एक विधि लागू करते हैं, तो कॉल कंटेनर में जाता है जो इंटरसेप्टर, डेकोरेटर आदि के माध्यम से कॉल भेजेगा, साथ ही किसी भी लेनदेन या सुरक्षा जांच का भी ध्यान रखेगा। एक बार जब यह सब हो जाता है, तो कॉल अंत में वास्तविक वस्तु पर जाता है और परिणाम प्रॉक्सी से कॉलर को वापस भेज दिया जाता है।

अंतर केवल इस बात में आता है कि किस तरह से वस्तु को हल किया जाए। "सुलझाया हुआ" से हमारा सीधा सा मतलब है कि, कंटेनर को वास्तविक आक्रमण के लिए कहाँ और कैसे दिखता है।

CDI में कंटेनर एक "स्कोप" में दिखता है, जो मूल रूप से एक हैशमैप होगा जो एक विशिष्ट अवधि (प्रति अनुरोध @RequestScoped, HTTP सत्र @SessionScoped, प्रति एप्लिकेशन @ApplicationScoped, JSF वार्तालाप @ConversationScoped, या आपके कस्टम स्कोप कार्यान्वयन) के लिए रहता है।

EJB में कंटेनर भी हैशमैप में दिखता है अगर बीन टाइप का हो @Stateful। एक @Statefulसेम भी यह रहते हैं और दायरे में अन्य सभी सेम के साथ मरने के लिए पैदा कर रहा ऊपर दिए गए क्षेत्र एनोटेशन के किसी भी उपयोग कर सकते हैं। EJB @Statefulमें अनिवार्य रूप से "किसी भी scoped" बीन है। @Statelessमूल रूप से एक उदाहरण पूल है - आप एक मंगलाचरण की अवधि के लिए पूल से एक उदाहरण मिलता है। @Singletonअनिवार्य रूप से है@ApplicationScoped

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

वे वर्तमान में सेवाओं के संदर्भ में समान नहीं हैं जो कंटेनर इस प्रस्तावना को करते समय पेश करेगा, लेकिन जैसा कि मैं कहता हूं कि हम इस पर जावा ईई युक्ति स्तर पर काम कर रहे हैं।

प्रदर्शन नोट

किसी भी "प्रकाश" या "भारी" मानसिक छवियों की उपेक्षा करें। वह सब मार्केटिंग है। उनके पास अधिकांश भाग के लिए एक ही आंतरिक डिजाइन है। CDI इंस्टेंस रिज़ॉल्यूशन शायद थोड़ा अधिक जटिल है क्योंकि यह थोड़ा अधिक गतिशील और प्रासंगिक है। EJB उदाहरण संकल्प तुलनात्मक रूप से स्थिर, गूंगा और सरल है।

मैं आपको टॉमईई में एक कार्यान्वयन के दृष्टिकोण से बता सकता हूं, एक ईजेबी बनाम एक सीडीआई बीन को लागू करने के बीच शून्य प्रदर्शन अंतर है।

पीओजेओ के लिए डिफ़ॉल्ट, फिर सीडीआई, फिर ईजेबी

जब कोई लाभ न हो तो बेशक CDI या EJB का उपयोग न करें। जब आप इंजेक्शन, ईवेंट, इंटरसेप्टर, डेकोरेटर्स, जीवनचक्र ट्रैकिंग और इस तरह की चीजें चाहते हैं, तो सीडीआई में फेंक दें। वह ज्यादातर समय है।

उन बुनियादी बातों के अलावा, उपयोगी कंटेनर सेवाओं की एक नंबर पर आप केवल उपयोग करने का विकल्प है यदि आप अपने CDI सेम भी जोड़कर एक EJB कर रहे हैं @Stateful, @Statelessया @Singletonउस पर।

यहाँ एक छोटी सूची है जब मैं ईजेबी को तोड़ता हूं।

JAX-WS का उपयोग करना

JAX-WS को एक्सपोज़ करना @WebService। मैं आलसी हूँ। जब @WebServiceएक EJB भी होता है, तो आपको इसे सूचीबद्ध करने और web.xmlफ़ाइल में एक सर्वलेट के रूप में मैप करने की आवश्यकता नहीं है । यही मेरे लिए काम है। साथ ही मुझे नीचे उल्लिखित किसी भी अन्य कार्यक्षमता का उपयोग करने का विकल्प मिलता है। इसलिए यह मेरे लिए एक नो-ब्रेनर है।

के लिए उपलब्ध है @Statelessऔर @Singletonकेवल।

JAX-RS का उपयोग करना

JAX-RS संसाधन के माध्यम से एक्सपोज़ करना @Path। मैं अभी भी आलसी हूँ। जब Restful सेवा भी एक EJB है, तो फिर से आपको स्वचालित खोज मिलती है और इसे JAX-RS Applicationउपवर्ग या उस जैसी किसी भी चीज़ से नहीं जोड़ना पड़ता । इसके अलावा मैं ठीक उसी सेम को बेनकाब कर सकता हूं जैसे @WebServiceकि मैं नीचे बताई गई किसी भी महान कार्यक्षमता का उपयोग करना चाहता हूं या करना चाहता हूं।

के लिए उपलब्ध है @Statelessऔर @Singletonकेवल।

स्टार्टअप तर्क

स्टार्टअप के माध्यम से लोड करें @Startup। सीडीआई में वर्तमान में इसके बराबर नहीं है। किसी तरह हम AfterStartupकंटेनर जीवन चक्र में एक घटना की तरह कुछ जोड़ने से चूक गए । अगर हमने ऐसा किया होता, तो आप बस एक @ApplicationScopedबीन रख सकते थे जो इसके लिए सुनता था और यह प्रभावी रूप से एक के @Singletonसाथ एक ही होगा @Startup। यह सीडीआई 1.1 की सूची में है।

के लिए उपलब्ध है @Singleton

समानांतर में काम करना

@Asynchronousविधि मंगलाचरण। थ्रेड्स शुरू करना किसी भी सर्वर-साइड वातावरण में एक नहीं-नहीं है। बहुत सारे धागे होने से एक गंभीर प्रदर्शन हत्यारा है। यह एनोटेशन आपको कंटेनर के थ्रेड पूल का उपयोग करने वाली चीजों को समानांतर करने की अनुमति देता है। यह कमाल का है।

के लिए उपलब्ध है @Stateful, @Statelessऔर @Singleton

नियत कार्य

@Scheduleया ScheduleExpressionमूल रूप से एक क्रोन या Quartzकार्यक्षमता है। साथ ही बहुत भयानक। अधिकांश कंटेनर इसके लिए कवर के नीचे सिर्फ क्वार्ट्ज का उपयोग करते हैं। हालांकि, ज्यादातर लोग नहीं जानते कि जावा ईई में शेड्यूलिंग का काम लेन-देन का है! यदि आप एक डेटाबेस को अपडेट करते हैं तो कुछ काम को शेड्यूल करें और उनमें से एक विफल हो जाता है, दोनों स्वचालित रूप से साफ हो जाएंगे। अगर दEntityManager लगातार कॉल विफल रहता है या फ्लशिंग की समस्या है, तो कार्य को अन-शेड्यूल करने की कोई आवश्यकता नहीं है। याय, लेन-देन।

के लिए उपलब्ध है @Statelessऔर @Singletonकेवल।

एक JTA लेनदेन में EntityManagers का उपयोग करना

उपरोक्त लेन-देन पर निश्चित रूप से आपको एक JTAप्रबंधित का उपयोग करने की आवश्यकता है EntityManager। आप उन्हें सादे "सीडीआई" के साथ उपयोग कर सकते हैं, लेकिन कंटेनर-प्रबंधित लेनदेन के बिना यह UserTransactionकमिट / रोलबैक लॉजिक को दोहराकर वास्तव में एकरस हो सकता है।

CDI, JSF सहित सभी जावा ईई घटकों के लिए उपलब्ध @ManagedBean, @WebServlet, @WebListener, @WebFilter, आदि @TransactionAttributeएनोटेशन, हालांकि, उपलब्ध है @Stateful, @Statelessऔर @Singletonकेवल।

जेटीए को प्रबंधित रखना EntityManager

EXTENDEDकामयाब EntityManagerआप एक रखने के लिए अनुमति देता है EntityManagerके बीच खुले JTAलेनदेन और नहीं खो संचित डेटा। सही समय और स्थान के लिए अच्छी सुविधा। जिम्मेदारी से उपयोग करें :)

के लिए उपलब्ध है @Stateful

आसान तुल्यकालन

जब आपको सिंक्रनाइज़ेशन की आवश्यकता होती है, @Lock(READ)और @Lock(WRITE)एनोटेशन बहुत उत्कृष्ट होते हैं। यह आपको मुफ्त में समवर्ती पहुँच प्रबंधन प्राप्त करने की अनुमति देता है। सभी ReentrantReadWriteLock पाइपलाइन छोड़ें। एक ही बाल्टी में @AccessTimeout, जो आपको यह कहने की अनुमति देता है कि कितने समय तक एक धागा देने से पहले सेम उदाहरण तक पहुंचने के लिए इंतजार करना चाहिए।

@Singletonकेवल सेम के लिए उपलब्ध है ।


32
डेविड को बहुत अच्छा लगता है :) मुझे लगता है कि आपने इसे कवर किया है।
लाइटगार्ड

7
इस उत्तर के लिए धन्यवाद। आपने मेरे सिर में छाले को साफ किया है और बहुत सारे डॉट्स को जोड़ा है।
Thupten

7
यह उस विषय पर अब तक का सबसे अच्छा स्पष्टीकरण है जिसे मैंने कभी पढ़ा है। यह वास्तविक जीवन में ईजेबी के लगभग सभी महत्वपूर्ण पहलुओं को भी शामिल करता है। अच्छा कार्य!!
nanoquack

3
बहुत समझदार और आदम सख्त कानूनी शब्दों में गलत नहीं है, लेकिन भेद मूक है। युक्ति कहती है कि EJB उदाहरण प्रासंगिक नहीं है, लेकिन फिर बाद में EJB के संदर्भ (प्रॉक्सी) को प्रासंगिक कहा जाता है। एक स्टेटफुल बीन का जीवनचक्र पूरी तरह से संदर्भ (प्रॉक्सी) के माध्यम से नियंत्रित किया जाता है, इसलिए जब CDI कंटेनर उस संदर्भ (प्रॉक्सी) को नियंत्रित कर रहा है तो गणित समान आता है - स्टेटफुल EJBs प्रभावी रूप से प्रासंगिक हो सकते हैं।
डेविड बोलिव्स

3
क्या आपने टीईएसएलए में अपने लंच ब्रेक पर यह लिखा था?
एडिसन

2

यदि आप वास्तव में ejb 3.1 की किसी भी विशेषता का उपयोग नहीं कर रहे हैं, तो इसका उत्तर सरल है। लेकिन लगता है कि आपकी खोज इंगित करती है कि आपको संदेह है कि ejb 3.1 अवधारणाएं हैं जिनके बारे में आपको जानकारी नहीं होने से आप लाभ उठा रहे हैं। एक उदाहरण यह हो सकता है कि कंटेनर स्लैब का एक पूल इस्तेमाल करने के लिए तैयार रख सकता है, ताकि जेएमएस और डेटाबेस कनेक्शन को अनुरोध के हिस्से के रूप में इंजेक्ट न करना पड़े।

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.