स्प्रिंग डेटा रिपॉजिटरी वास्तव में कैसे लागू की जाती हैं?


111

मैं कुछ समय से अपनी परियोजना में स्प्रिंग डेटा जेपीए रिपॉजिटरी के साथ काम कर रहा हूं और मुझे नीचे दिए गए बिंदुओं का पता है:

  • रिपॉजिटरी इंटरफेस में, हम इस तरह के तरीकों को जोड़ सकते हैं findByCustomerNameAndPhone()(मान लेते हैं customerNameऔर phoneडोमेन ऑब्जेक्ट में फ़ील्ड हैं)।
  • फिर, स्प्रिंग रनटाइम (एप्लिकेशन रन के दौरान) में उपरोक्त रिपॉजिटरी इंटरफ़ेस विधियों को लागू करके कार्यान्वयन प्रदान करता है।

मुझे इस पर दिलचस्पी है कि यह कैसे कोडित किया गया है और मैंने स्प्रिंग जेपीए स्रोत कोड और एपीआई पर ध्यान दिया है, लेकिन मुझे नीचे दिए गए सवालों के जवाब नहीं मिले:

  1. रनटाइम एंड मेथड्स में रिपॉजिटरी इम्प्लीमेंटेशन क्लास को कैसे लागू किया जाता है और उसे कैसे इंजेक्ट किया जाता है?
  2. क्या स्प्रिंग डेटा JPA विधियों को लागू करने और गतिशील रूप से इंजेक्ट करने के लिए CGlib या किसी भी बाईटेकोड हेरफेर लाइब्रेरी का उपयोग करता है?

क्या आप उपरोक्त प्रश्नों में मदद कर सकते हैं और कोई समर्थित दस्तावेज भी प्रदान कर सकते हैं?

जवाबों:


144

सबसे पहले, कोई कोड पीढ़ी नहीं चल रही है, जिसका अर्थ है: कोई CGLib, कोई बाइट-कोड पीढ़ी बिल्कुल नहीं। मौलिक दृष्टिकोण यह है कि ProxyFactoryइंटरफ़ेस को वापस करने के लिए स्प्रिंग के एपीआई का उपयोग करके एक जेडीके प्रॉक्सी उदाहरण प्रोग्रामेटिक रूप से बनाया गया है और MethodInterceptorउदाहरण के लिए सभी कॉल्स को इंटरसेप्ट करता है और विधि को उपयुक्त स्थानों में रूट करता है:

  1. यदि रिपॉजिटरी को एक कस्टम कार्यान्वयन भाग के साथ प्रारंभ किया गया है ( विवरण के लिए संदर्भ प्रलेखन का वह भाग देखें), और जिस विधि को लागू किया गया है, वह उस वर्ग में लागू किया गया है, तो कॉल को वहां रूट किया जाता है।
  2. यदि विधि एक क्वेरी विधि है (देखें DefaultRepositoryInformationकि यह कैसे निर्धारित किया जाता है), तो स्टोर विशिष्ट क्वेरी निष्पादन तंत्र स्टार्टअप में उस विधि के लिए निष्पादित की जाने वाली क्वेरी को निष्पादित और निष्पादित करता है। इसके लिए एक रिज़ॉल्यूशन मैकेनिज़्म है जो विभिन्न स्थानों @Queryपर स्पष्ट रूप से घोषित प्रश्नों की पहचान करने की कोशिश करता है ( विधि का उपयोग करके , जेपीए नामांकित क्वेरीज़) अंततः विधि नाम से क्वेरी व्युत्पत्ति के लिए वापस गिर रहा है। क्वेरी तंत्र का पता लगाने के लिए, देखें JpaQueryLookupStrategy। क्वेरी व्युत्पत्ति के लिए पार्सिंग लॉजिक पाया जा सकता है PartTree। वास्तविक क्वेरी में स्टोर विशिष्ट अनुवाद को उदाहरण में देखा जा सकता है JpaQueryCreator
  3. यदि उपर्युक्त में से कोई भी लागू नहीं होता है, तो स्टोर-स्पेसिफिक रिपॉजिटरी बेस क्लास ( SimpleJpaRepositoryजेपीए के मामले में) द्वारा कार्यान्वित की जाने वाली विधि को लागू करना पड़ता है और कॉल उसी के उदाहरण में रूट हो जाता है।

उस रूटिंग लॉजिक को लागू करने का तरीका इंटरसेप्टर है QueryExecutorMethodInterceptor, उच्च स्तरीय रूटिंग लॉजिक यहां पाया जा सकता है

उन परदे के पीछे का निर्माण मानक जावा आधारित फैक्ट्री पैटर्न कार्यान्वयन में संलग्न है। उच्च-स्तरीय प्रॉक्सी निर्माण में पाया जा सकता है RepositoryFactorySupport। स्टोर-विशिष्ट कार्यान्वयन फिर आवश्यक अवसंरचना घटक जोड़ते हैं ताकि JPA के लिए आप आगे बढ़ें और बस इस तरह कोड लिखें:

EntityManager em =  // obtain an EntityManager
JpaRepositoryFactory factory = new JpaRepositoryFactory(em);
UserRepository repository = factory.getRepository(UserRepository.class);

स्पष्ट रूप से उल्लेख करने का कारण यह है कि यह स्पष्ट हो जाना चाहिए कि, इसके मूल में, उस कोड में से किसी को भी वसंत कंटेनर को पहले स्थान पर चलाने की आवश्यकता नहीं है। यह वसंत को क्लासपाथ पर एक पुस्तकालय के रूप में चाहिए (क्योंकि हम पहिया को सुदृढ़ नहीं करना चाहते हैं), लेकिन सामान्य रूप से कंटेनर अज्ञेयवादी है।

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


3
हाय ओलिवर, क्या आप इस बारे में विस्तार से बता सकते हैं कि वसंत @Repositoryपहले स्थान पर एनोटेट इंटरफेस को कैसे दिखाता है? RepositoryFactorySupport#getRepository()शो को देखते हुए कि यह इंटरफ़ेस क्लास को एक पैरामीटर के रूप में लेता है, इसलिए इसे कहीं और खोजा जाना चाहिए। मैं विशेष रूप से यह पता लगाने की कोशिश कर रहा हूं कि एक एनोटेट इंटरफेस कैसे खोजा जा सकता है और स्वचालित रूप से एक जेडीके प्रॉक्सी बीन उत्पन्न करता है जो इंटरफ़ेस को लागू करता है, बहुत अधिक स्प्रिंग-डेटा की तरह, लेकिन एक आवेदन-विशिष्ट उद्देश्य के लिए रिपॉजिटरी से संबंधित नहीं।
क्रिस राइस

1
आप पर एक नज़र रखना चाहते हो सकता है RepositoryComponentProvider। कोई स्वचालित चीज़ नहीं हो रही है, लेकिन कुछ प्रकारों के लिए एक घटक स्कैन (या तो एनोटेट या एनोटेशन लेकर) और FactoryBeanउनमें से प्रत्येक के लिए कॉन्फ़िगर किया गया है।
ओलिवर ड्रोट्बोहम

2
एक पुराने धागे पर टिप्पणी करने के लिए क्षमा करें, लेकिन जिज्ञासु थे ... क्या रिपॉजिटरी प्रॉक्सिस सिंगलटन ऑब्जेक्ट हैं? हम एक समस्या देख रहे हैं जिससे हमारा कोड रेपो विधि को कॉल करने की कोशिश कर रहा है, लेकिन यह कभी भी प्रॉक्सी पर कॉल करने में सक्षम नहीं लगता है। यह बस लटका रहता है। मुझे आश्चर्य है कि अगर यह एक सिंगलटन की प्रतीक्षा कर रहा है जो व्यस्त है।
इयुविवि
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.