Tạo mới một Maven multi-module project

Thông thường đối với các ứng dụng nhỏ, khi sử dụng Apache Maven để quản lý các dependencies của project, chúng ta sẽ tạo một Maven project như bình thường, bao gồm một tập tin pom.xml và source code của ứng dụng. Nhưng đối với các ứng dụng lớn như ứng dụng Microservices chẳng hạn, các bạn sẽ có nhu cầu chia nhỏ ra nhiều project khác nhau, để dễ quản lý source code và maintain ứng dụng. Apache Maven cũng hỗ trợ chúng ta làm được điều này bằng cách sử dụng một Maven multi-module project. Trong bài viết này, mình sẽ hướng dẫn các bạn cách tạo mới một Maven multi-module project và làm thế nào để quản lý các dependencies một cách hiệu quả nhất, các bạn nhé!

Để tạo một Maven multi-module project, đầu tiên các bạn hãy tạo mới một Maven project các bạn nhé:

Tập tin pom.xml trong thư mục root của project sẽ đóng vai trò tập tin Parent POM. Các bạn cần khai báo packaging type của tập tin pom.xml này là pom nha các bạn:

Tập tin pom.xml này sẽ giúp chúng ta định nghĩa các properties sử dụng chung cho tất cả các module của project. Các bạn có thể sử dụng nó để quản lý tất cả các dependencies, plugins mà chúng ta muốn sử dụng cho project. Các common configuration hay Maven setting, các bạn cũng có thể sử dụng tập tin này để định nghĩa.

Bây giờ, để thêm mới một module vào project, trong IntelliJ IDE, các bạn có thể right-click vào project -> chọn New -> chọn Module…:

Điền thông tin cho module theo nhu cầu của mình:

Rồi nhấn nút Create, các bạn sẽ thấy một module được tạo bên trong thư mục root của project như sau:

Trong tập tin parent POM lúc này các bạn sẽ thấy, module mới mà chúng ta vừa tạo được khai báo sử dụng tag <module> như sau:

Với khai báo này, tập tin pom.xml ở thư mục root của project còn được gọi là Aggregator POM, chịu trách nhiệm gom nhóm và điều phối việc build các module cùng lúc, đó các bạn. Khi build project, Maven sẽ sử dụng cơ chế Reactor Build để tự động phân tích, sắp xếp và build các module theo một thứ tự logic dựa trên đồ thị phụ thuộc (dependency graph) giữa các module.

Trong tập tin pom.xml của module1, các bạn sẽ thấy thông tin Parent POM được khai báo sử dụng thông tin Maven dependency của root project như sau:

Các bạn có thể thêm mới module2 vào project để xem kết quả như thế nào, các bạn nhé. Của mình như sau:

Tập tin pom.xml ở thư mục root của project sẽ thêm module2 vào như sau:

Giá trị được khai báo trong thẻ <module> là tên thư mục nằm trong thư mục root của project, không phải là artifactId của module, các bạn nhé!

Module dependencies

Việc khai báo module trong tập tin pom.xml ở thư mục root của project sẽ không tạo dependency giữa các modules, các bạn nhé. Nếu module1 depend vào module2 thì các bạn cần phải khai báo module2 dependency trong tập tin pom.xml của module1, ví dụ như sau:

Cấu hình properties

Khi tạo mới module trong IntelliJ IDE, mặc định trong tập tin pom.xml của mỗi module đều định nghĩa các properties như sau:

Vì các properties này đã được định nghĩa ở tập tin parent POM nên các bạn có thể remove những properties này các bạn nhé!

Những properties cần sử dụng cho project, các bạn có thể định nghĩa trong tập tin Parent POM, các module chỉ cần sử dụng lại mà thôi. Các bạn có thể khai báo thông tin version của các dependencies sử dụng properties và trong các module, chỉ cần sử dụng lại các properties này.

Dependencies management

Nếu các module của project sử dụng cùng một dependency, thay vì chúng ta khai báo thông tin dependency cùng với version của nó cho từng module, thì các bạn có thể khai báo dependency này trong tập tin parent POM sử dụng thẻ <dependencyManagement>, ví dụ như sau:

Trong từng module, để sử dụng dependency đó, các bạn chỉ cần khai báo nó mà không cần khai báo thông tin version như sau:

Thẻ <dependencyManagement>  chỉ đơn giản là khai báo thông tin dependency cùng với version của nó thôi các bạn nhé. Chỉ khi nào các bạn khai báo thông tin dependency trong các module thì dependency này mới thực sự được thêm vào classpath của module đó.

Plugins management

Ngoài việc khai báo dependencyManagement trong tập tin Parent POM thì các bạn cũng có thể khai báo thông tin các plugins cùng với cấu hình của chúng trong tập tin Parent POM, để các module có thể khai báo sử dụng các plugins này.

Ví dụ như nếu project của các bạn có sử dụng thư viện Lombok để tự động generate code cho các đoạn code common thì các bạn có thể cấu hình Maven Compiler Plugin để nó process các đoạn code liên quan đến Lombok trước, trong tập tin Parent POM sử dụng thẻ <pluginManagement> như sau:

Sau đó thì chỉ cần khai báo sử dụng Maven Compiler Plugin trong các module là được:

Khi compile code trong module1, Maven sẽ sử dụng cấu hình mà chúng ta đã khai báo trong tập tin Parent POM và process cho các đoạn code liên quan đến Lombok trước, đó các bạn!

Reactor Build

Như mình đã nói ở trên, với cơ chế Reactor build, Maven sẽ tự động phân tích, sắp xếp và build các module theo một thứ tự logic. Nên lúc này, nếu các bạn build project sử dụng command:

các bạn sẽ thấy kết quả như sau:

Parent POM sẽ được build trước tiên để các module1 và module2 có thể sử dụng các thông tin được khai báo trong tập tin Parent POM. Tiếp theo, vì module1 khai báo depend vào module2 nên như các bạn thấy, module2 được build tiếp theo. Và cuối cùng thì mới tới module1. Việc khai báo thông tin module trong tập tin Aggregator POM sẽ không quyết định thứ tự build, các bạn nhé!

Mặc định, command:

sẽ build hết tất cả các module trong project. Nếu các bạn chỉ muốn build 1 hoặc nhiều module nhất định thì có thể sử dụng command:

hoặc

Ví dụ, nếu mình chỉ muốn build module1 thì mình sẽ chạy command:

Kết quả như sau:

Nếu muốn build nhiều module thì các module này sẽ cách nhau bằng dấu phẩy các bạn nhé!

Nếu các bạn muốn build một module nào đó cùng với các module dependencies thì có thể thêm tham số -am, như sau:

Kết quả:

Như vậy là trong bài viết này, mình đã hướng dẫn các bạn cách tạo mới một Maven multi-module project. Việc hiểu và áp dụng đúng sẽ giúp chúng ta quản lý source code của ứng dụng với Maven hiệu quả hơn, đó các bạn!

Add Comment