परिचय: Java प्रोजेक्ट्स में मोनोरेपॉजिटरी क्यों?
Java अनुप्रयोगों की जटिलता बढ़ने के साथ, टीमों को अक्सर एक दुविधा का सामना करना पड़ता है: सारा कोड एक रिपॉजिटरी (मोनोरेपॉजिटरी) में रखें या इसे कई माइक्रोसर्विस रिपॉजिटरी (पॉलीरेपॉजिटरी) में विभाजित करें। अभ्यास से पता चलता है कि मोनोरेपॉजिटरी सामान्य व्यावसायिक तर्क, लाइब्रेरी और कॉन्फ़िगरेशन वाले प्रोजेक्ट्स के लिए विशेष रूप से प्रभावी है। Java में, यह निर्भरता, संस्करणों और बिल्ड को केंद्रीय रूप से प्रबंधित करने की अनुमति देता है, जिससे रीफैक्टरिंग और एकीकरण सरल हो जाता है।
इस लेख में, हम विश्लेषण करेंगे कि व्यवहार में मोनोरेपॉजिटरी में Java कोड को कैसे व्यवस्थित किया जाए: फ़ोल्डर संरचना से लेकर CI/CD सेटअप तक। आप जानेंगे कि सामान्य गलतियों से कैसे बचें और विकास को कैसे गति दें।
1. Java के लिए मोनोरेपॉजिटरी संरचना
मोनोरेपॉजिटरी का मुख्य सिद्धांत मॉड्यूलरिटी है। Java में, इसे मल्टी-मॉड्यूल प्रोजेक्ट्स के माध्यम से कार्यान्वित किया जाता है। प्रत्येक मॉड्यूल अपने जिम्मेदारी क्षेत्र के लिए जिम्मेदार है: सामान्य लाइब्रेरी, सेवाएं, उपयोगिताएँ।
एक विशिष्ट संरचना का उदाहरण:
my-java-monorepo/├── build.gradle # रूट बिल्ड फ़ाइल├── settings.gradle # सभी मॉड्यूल को जोड़ता है├── gradle.properties # सामान्य निर्भरता संस्करण├── common-lib/ # सामान्य लाइब्रेरी (DTO, उपयोगिताएँ)│ ├── build.gradle│ └── src/├── service-auth/ # प्रमाणीकरण सेवा│ ├── build.gradle│ └── src/├── service-payment/ # भुगतान सेवा│ ├── build.gradle│ └── src/└── integration-tests/ # एकीकरण परीक्षण ├── build.gradle └── src/संस्करण प्रबंधन के लिए, सामान्य निर्भरताओं को रूट फ़ाइल build.gradle या pom.xml (Maven के लिए) में रखना सुविधाजनक है। Gradle में, यह subprojects ब्लॉक के माध्यम से किया जाता है:
subprojects { apply plugin: 'java' group = 'com.pythonlib' version = '1.0.0'
repositories { mavenCentral() }
dependencies { testImplementation 'org.junit.jupiter:junit-jupiter:5.10.0' }}ऐसी संरचना कॉन्फ़िगरेशन की प्रतिलिपि बनाए बिना नई सेवाओं को आसानी से जोड़ने की अनुमति देती है, और यह सुनिश्चित करती है कि सभी मॉड्यूल लाइब्रेरी के समान संस्करणों का उपयोग करते हैं।
2. निर्भरता और संस्करण प्रबंधन
मोनोरेपॉजिटरी की मुख्य समस्याओं में से एक संस्करण विरोध है। Java में, इसे हल करने के लिए BOM (Bill of Materials) या निर्भरताओं के केंद्रीकृत विवरण का उपयोग किया जाता है। आइए java-platform का उपयोग करके Gradle पर एक उदाहरण देखें।
हम एक platform मॉड्यूल बनाएंगे जो सभी बाहरी निर्भरताओं को परिभाषित करता है:
// platform/build.gradleplugins { id 'java-platform'}
javaPlatform { allowDependencies()}
dependencies { constraints { api 'com.fasterxml.jackson.core:jackson-databind:2.15.2' api 'org.springframework.boot:spring-boot-starter-web:3.1.5' api 'org.slf4j:slf4j-api:2.0.9' }}अब प्रत्येक सेवा में, आप बस प्लेटफ़ॉर्म का संदर्भ ले सकते हैं:
// service-auth/build.gradledependencies { implementation platform(project(':platform')) implementation 'com.fasterxml.jackson.core:jackson-databind' implementation 'org.springframework.boot:spring-boot-starter-web'}यह सुनिश्चित करता है कि सभी मॉड्यूल समान संस्करणों का उपयोग करते हैं। platform में संस्करण अपडेट करने पर, परिवर्तन स्वचालित रूप से सभी सेवाओं पर लागू होते हैं।
सुझाव: Maven के लिए, रूट pom.xml में <dependencyManagement> का उपयोग करें। यह समान रूप से काम करता है।
3. मोनोरेपॉजिटरी के लिए CI/CD
मोनोरेपॉजिटरी में सतत एकीकरण को व्यवस्थित करने के लिए एक विशेष दृष्टिकोण की आवश्यकता होती है। प्रत्येक कमिट पर सभी मॉड्यूल को बिल्ड नहीं किया जा सकता - इससे पाइपलाइन धीमी हो जाएगी। इष्टतम समाधान परिवर्तनों के आधार पर इंक्रीमेंटल बिल्ड है।
paths का उपयोग करके GitHub Actions पर एक उदाहरण:
name: Java CIon: