Maven'de Çoklu Modül (Multi Module) Yapısı Nasıl Oluşturulur?
Büyük Java ve Spring Boot projelerinde kodları tek bir proje altında toplamak yerine Maven Multi Module yapısı kullanmak oldukça yaygındır. Bu yapı sayesinde ortak kodları farklı modüllerde tutabilir, modüller arasında bağımlılık kurabilir ve tüm projeyi tek bir yerden yönetebiliriz.
Ben de projelerimde ortak yapıları ayrı modüller halinde kullanırken bu yöntemi tercih ediyorum. Bu yazıda Maven'de çoklu modül yapısını adım adım anlatıyorum.
Maven Multi Module Yapısının Mantığı
Multi Module yapısında bir root (ana) Maven projesi bulunur. Bu proje kendi içerisinde bir veya daha fazla child module barındırır.
Örnek proje yapısı şu şekilde düşünülebilir:
root-project │── pom.xml │ ├── common-module │ └── pom.xml │ ├── user-module │ └── pom.xml │ └── order-module └── pom.xml
Burada root proje tüm modülleri yönetirken, her child module kendi içerisinde bağımsız bir Maven projesidir.
1. Root Maven Projesini Oluşturmak
İlk adım olarak yeni bir Maven projesi oluşturuyorum. Bu proje uygulamanın çalıştığı proje değil, diğer modülleri yöneten ana proje oluyor.
Root projenin temel görevi:
- Alt modülleri yönetmek.
- Ortak dependency ve plugin yapılandırmalarını paylaşmak.
- Tüm modülleri tek komutla build edebilmek.
2. Child Module Oluşturmak
Root projenin içerisine yeni bir Maven modülü oluşturuyorum.
Burada dikkat edilmesi gereken en önemli nokta, child modülün pom.xml dosyasındaki <parent> alanının root projeyi göstermesidir.
<parent> <groupId>com.example</groupId> <artifactId>root-project</artifactId> <version>1.0.0</version> </parent>
Bu tanımlama sayesinde child module root projenin ayarlarını devralır.
3. Root pom.xml Dosyasına Modülleri Eklemek
Eğer IntelliJ IDEA kullanıyorsam yeni modül oluşturduğumda root projenin pom.xml dosyası çoğu zaman otomatik güncelleniyor.
Manuel yapmak istersem root projenin pom.xml dosyasında iki önemli tanımlama yapıyorum.
packaging Tanımı
Root proje çalıştırılabilir bir uygulama olmadığı için paketleme tipi pom olmalıdır.
<packaging>pom</packaging>
modules Tanımı
Alt modülleri root projede <modules> etiketi içerisinde tanımlıyorum.
<modules> <module>common-module</module> <module>user-module</module> <module>order-module</module> </modules>
Buraya eklediğim her modül Maven tarafından build sürecine dahil edilir.
4. Spring Boot Parent Kullanımı
Eğer proje bir Spring Boot projesiyse root projenin parent'ını spring-boot-starter-parent olarak tanımlayabiliyorum.
<parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>3.x.x</version> </parent>
Bunun bana sağladığı avantajlar:
- Spring Boot'un önerdiği dependency sürümlerini otomatik kullanırım.
- Dependency eklerken çoğu zaman ayrıca sürüm belirtmem gerekmez.
- Uyumsuz dependency sürümleriyle uğraşmam.
Örneğin aşağıdaki dependency'de sürüm yazmama gerek kalmaz.
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency>
Spring Boot parent gerekli sürümü kendisi belirler.
5. Dependency Sürümünü Override Etmek (dependencyManagement)
Bazı durumlarda Spring Boot'un verdiği dependency sürümünden farklı bir sürüm kullanmak isteyebilirim.
Bunun için <dependencyManagement> alanını kullanıyorum.
<dependencyManagement> <dependencies> <dependency> <groupId>org.projectlombok</groupId> <artifactId>lombok</artifactId> <version>1.18.42</version> </dependency> </dependencies> </dependencyManagement>
Bu yapı sayesinde tüm modüller aynı Lombok sürümünü kullanabilir.
Önemli not: dependencyManagement dependency eklemez. Sadece kullanılacak sürümü merkezi olarak belirler.
6. Ortak Sürümleri properties İçerisinde Yönetmek
Java sürümü veya projede kullanılan ortak kütüphanelerin sürümlerini tek bir yerden yönetmek istiyorsam <properties> alanını kullanıyorum.
<properties> <java.version>21</java.version> <lombok.version>1.18.42</lombok.version> <mapstruct.version>1.6.3</mapstruct.version> </properties>
Daha sonra dependency içerisinde bu değişkenleri kullanabiliyorum.
<dependency> <groupId>org.projectlombok</groupId> <artifactId>lombok</artifactId> <version>${lombok.version}</version> </dependency>
Bu yöntemin avantajı, sürüm değişikliği gerektiğinde sadece properties bölümünü güncellememin yeterli olmasıdır.
Bir Modül İçerisinde Başka Bir Modülü Kullanmak
Bir modülün başka bir modülü kullanabilmesi için, kullanacağı modülü dependency olarak eklemesi yeterlidir.
Örneğin user-module, common-module'ü kullanacaksa:
<dependency> <groupId>com.example</groupId> <artifactId>common-module</artifactId> </dependency>
Eğer iki modül aynı root proje altında bulunuyorsa Maven bu bağımlılığı otomatik olarak çözer ve build sırasında ilgili modülü de derler.
Maven Multi Module Yapısının Avantajları
| Avantaj | Açıklama |
|---|---|
| Ortak kod kullanımı | Tekrar eden sınıfları ortak bir modülde toplayabiliriz. |
| Merkezi dependency yönetimi | Tüm modüller aynı dependency sürümlerini kullanır. |
| Tek komutla build | Root proje üzerinden tüm modüller birlikte derlenebilir. |
| Bağımsız modüller | Her modül kendi sorumluluğuna göre geliştirilebilir. |
| Düzenli proje yapısı | Büyük Spring Boot projelerinde daha okunabilir bir mimari sağlar. |
Kısaca Özet
- Root proje
<packaging>pom</packaging>olarak tanımlanır. - Child modüller
<parent>etiketi ile root projeye bağlanır. <modules>alanında tüm alt modüller listelenir.- Spring Boot projelerinde
spring-boot-starter-parentdependency sürümlerini merkezi olarak yönetir. dependencyManagementile dependency sürümleri override edilebilir.propertiesalanı Java ve kütüphane sürümlerini tek noktadan yönetmek için kullanılır.
Sonuç
Maven Multi Module yapısı, özellikle büyük Spring Boot projelerinde kod organizasyonunu oldukça kolaylaştırıyor. Ortak modülleri farklı projelerde tekrar kullanabiliyor, dependency yönetimini tek bir yerden yapabiliyor ve tüm modülleri root proje üzerinden birlikte build edebiliyorum. Proje büyüdükçe bu yapı hem bakım hem de geliştirme sürecinde ciddi bir kolaylık sağlıyor.
