2013-02-13 15 views
21

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

+commons 
    +commons-api 
    +commons-impl 

मॉड्यूल की poms इस तरह विन्यस्त किया जाएगा कि कोई मॉड्यूल impl उप मॉड्यूल पर निर्भर करता है। इस तरह एक मॉड्यूल से कोई कोड किसी अन्य मॉड्यूल के कार्यान्वयन विवरण को "देखने" में सक्षम नहीं होगा।

हमें क्या परेशानी हो रही है, यह है कि हमारे वसंत एक्सएमएल कहां रखें। हमारी परियोजना हम स्वचालित रूप से वाइल्डकार्ड आयात का उपयोग वसंत एक्सएमएल फाइल को आयात

<import resource="classpath*:**/*-beans.xml"/>

इस तरह स्प्रिंग XMLs के स्थान वास्तव में, रनटाइम पर कोई फर्क नहीं पड़ता के रूप में सभी मॉड्यूल एक ही कक्षा लोडर में लोड करने के लिए और की तरह में , पीओएम में सख्त एक तरह निर्भरता नियम लागू नहीं होते हैं।

हालांकि, विकास के दौरान हम आईडीई चाहते हैं - हम इंटेलिज आईडीईए का उपयोग करते हैं - वसंत एक्सएमएल से संदर्भित कार्यान्वयन कक्षाओं को पहचानने के लिए। हम भी आईडीईए को अन्य मॉड्यूल में परिभाषित बीन्स को पहचानना चाहते हैं।

यदि हम वसंत एक्सएमएल को एपीआई सब-मॉड्यूल में डालते हैं - वे इम्प्ले उप-मॉड्यूल में कार्यान्वयन कक्षाओं को "देखें" नहीं देखेंगे। यदि हम उन्हें प्रत्यारोपण उप-मॉड्यूल में डालते हैं, तो उनके सेम अन्य मॉड्यूल से "देखा" नहीं जाएंगे। संभवतः आईडीईए प्रोजेक्ट को मॉड्यूल से स्प्रिंग एक्सएमएल को पहचानने के लिए कॉन्फ़िगर करना संभव है, जिस पर निर्भरता नहीं है, लेकिन हम अपने पीओएम को सभी परियोजना संरचना की जानकारी रखने के लिए पसंद करते हैं और आईडीईए परियोजना फाइलों पर भरोसा नहीं करते हैं।

हम स्प्रिंग एक्सएमएल (और शायद एक्सएमएल को भी हाइबरनेट) रखने के लिए एक तीसरा उप-मॉड्यूल बनाने पर विचार करते हैं। उदाहरण के लिए:

+commons 
    +commons-api 
    +commons-impl 
    +commons-config 

बाहरी मॉड्यूल दोनों कॉमन्स-api और कॉमन्स-config और कॉमन्स-config दोनों कॉमन्स-api और कॉमन्स-impl पर निर्भर करेगा पर निर्भर करेगा, पर निर्भरता के साथ कॉमन्स-इम्प्ल "प्रदत्त" (संक्रमणीय संकल्प को रोकने के लिए) के रूप में चिह्नित किया गया है।

हालांकि यह एक जटिल और अजीब समाधान की तरह लगता है और हमें लगता है कि मेवेन और स्प्रिंग के साथ इंटरफ़ेस/इम्प्लाइंडेशन को अलग करने के लिए एक बेहतर तरीका होना चाहिए।

+2

अच्छा सवाल है लेकिन अभी तक कोई जवाब नहीं है? क्या करुणा .. – cirit

+1

@cirit सहमत - बाउंटी – drewmoore

उत्तर

1

संक्षेप में आप चाहते हैं कि आइडिया मैवेन निर्भरता ग्राफ को ओवरराइड करें लेकिन इस कॉन्फ़िगरेशन को परियोजना फ़ाइलों में रखने से बचें?

एक विकल्प मैवेन प्रोफाइल में कार्यान्वयन निर्भरताओं को समूहित करना है। यह प्रोफ़ाइल डिफ़ॉल्ट रूप से सक्षम नहीं होगी लेकिन आप इसे विचार के तहत सक्रिय के रूप में चिह्नित करने में सक्षम होना चाहिए।

+0

शुरू किया मैं ग्राफ को पूरी तरह से ओवरराइड नहीं करना चाहता, मैं केवल स्प्रिंग एक्सएमएल फ़ाइलों को मैवेन प्रोजेक्ट्स में दिखाना चाहता हूं, जहां कोई निर्भरता मौजूद नहीं है ... – dkarlinsky

1

दो विचारों मन में आते हैं:

  1. आप एक (या अधिक) मॉड्यूल जहां सभी मॉड्यूल (एपीआई + impl) निर्भरता रहे हैं, इसलिए आप अपने वसंत विन्यास फाइल वहाँ लगा सके।
  2. एपीआई मॉड्यूल में वसंत कॉन्फ़िगरेशन फ़ाइलों को रखें और प्रपत्र provided के साथ इम्प्लोर मॉड्यूल पर निर्भरता घोषित करें इस तरह कार्यान्वयन ज्ञात होंगे, जबकि परिनियोजन के लिए एपीआई की कोई निर्भरता नहीं है।
6

आप क्या जरूरत है एक क्रम निर्भरता गुंजाइश है:

क्रम - यह गुंजाइश इंगित करता है कि निर्भरता संकलन के लिए आवश्यक नहीं है, लेकिन निष्पादन के लिए है। यह रनटाइम और टेस्ट क्लासपाथ में है, लेकिन संकलित क्लासपाथ नहीं है।

(https://maven.apache.org/guides/introduction/introduction-to-dependency-mechanism.html)

एक और impl मॉड्यूल जहां * -beans.xml config में impl वर्गों का उपयोग करने के एक impl मॉड्यूल से एक क्रम निर्भरता को परिभाषित करें। Intellij वसंत विन्यास फाइलों में इसे सही ढंग से पहचान लेगा, लेकिन कोड में उन्हें स्वतः पूरा नहीं करेगा (लेकिन यह परीक्षण कोड में ऐसा करेगा)।

यदि कोई भी कोड में कक्षाओं का उपयोग करता है, तो मेवेन के माध्यम से संकलन विफल हो जाएगा, क्योंकि रनटाइम निर्भरता एक संकलित वर्ग पथ पर नहीं है।बाहरी मॉड्यूल में क्रम दायरे में

1
  • कॉमन्स-impl

    1. कॉमन्स (पोम dependencyManagement) =>

      + कॉमन्स-api (संकलन)

      + कॉमन्स-impl (संकलन)

      + commons-config (संकलन)

    2. कॉमन्स-impl (पोम निर्भरता) =>

      + कॉमन्स-api (संकलन)

      + कॉमन्स-config (संकलन)

    3. बाहरी मॉड्यूल (पोम निर्भरता) =>

      + कॉमन्स-impl (क्रम)

      + कॉमन्स-api (संकलन)

      + कॉमन्स-config (संकलन)

2

आप इस तरह एपीआई और impl के decoupling प्राप्त कर सकते हैं:

+ commons (pom) 
    + pom.xml   <--- serves as a parent aggregator (see below) 
    + commons-api (jar) <--- contains models, interfaces and abstract classes only 
    + commons-impl (jar) <--- depends on commons-api 
    + commons-config (jar) <--- depends on commons-impl only (no need to depend on commons-api as it is brought in transitively) 

+ external-project (war or jar) <--- has commons-config as a dependency 

जनक एग्रीगेटर पोम (आदेश का निर्माण उल्लेख करें):

<modules> 
    <module>commons-api</module> 
    <module>commons-impl</module> 
    <module>commons-config</module> 
</modules> 

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

आपके कॉमन्स मॉड्यूल में होना चाहिए केवल एक ही कॉन्फ़िगरेशन आपके इम्प्लोर मॉड्यूल के परीक्षण पैकेज में होगा।

1
  1. मॉड्यूल संख्या जितना संभव हो सके रखें;

    यह गति निर्माण समय को गति देता है और इसके लेआउट को सरल बनाता है।

  2. मॉड्यूल संरचना को यथासंभव सादा रखें: एकल रूट + एक ही फ़ोल्डर में सभी उप मॉड्यूल, ई। जी।:

    pom.xml 
    commons-api/ 
    commons-runtime/ 
    module-a-api/ 
    module-a-runtime/ 
    ... 
    

इस परियोजना, जब मॉड्यूल संख्या वास्तव में अधिक है (> 50)

  1. क्रम को क्रम-दायरे वाले निर्भरता प्रदान भर में नेविगेशन को सरल मॉड्यूल केवल तभी आवश्यक होते हैं जब वे आवश्यक हों;

    यह आपके आर्किटेक्चर को स्पष्ट रखता है। किसी अन्य रनटाइम मॉड्यूल पर स्पष्ट निर्भरता के बजाय मैक्स का उपयोग करें।

  2. एपीआई मॉड्यूल में अपने एपीआई वसंत संदर्भ रखें, अपने सार्वजनिक बीन्स को सार बीन + इंटरफ़ेस के रूप में परिभाषित करें;

  3. रनटाइम मॉड्यूल में अपने कार्यान्वयन संदर्भ रखें, वसंत प्रोफाइल के माध्यम से अपने कार्यान्वयन के साथ एपी बीन्स को ओवरराइड करें (< बीन्स प्रोफाइल = "डिफ़ॉल्ट" का उपयोग करें)।

परिणाम: सरल, पारदर्शी लेआउट और डिज़ाइन; पूर्ण विचार समर्थन; रनटाइम मॉड्यूल आंतरिक पर कोई स्पष्ट निर्भरता नहीं है।