Trong bài viết trước, mình đã hướng dẫn các bạn cách tạo Maven Archetype cho một Maven project bình thường. Đối với các Maven multi-module project thì việc tạo Maven Archetype sẽ như thế nào? Chúng ta sẽ cùng nhau tìm hiểu trong bài viết này các bạn nhé!
Để làm ví dụ, mình sẽ lấy project ví dụ về Clean Architecture trong bài viết Giới thiệu về Clean Architecture – Phần 2 để xây dựng Maven Archetype cho project ví dụ này. Các bạn có thể tìm thấy source code của project ví dụ này tại đây https://github.com/khanhnguyenj/huongdanjava.com/tree/master/clean-architecture-example.
Đầu tiên, mình cũng sẽ tạo mới một Maven Archetype project sử dụng Maven Archetype maven-archetype-archetype, kết quả như sau:
Đầu tiên, mình sẽ copy nội dung của tập tin pom.xml trong project clean-architecture-example và replace nội dung của tập tin pom.xml tại thư mục src/main/resources/archetype-resources của project.
Chúng ta sẽ chỉnh sửa version của các dependencies để chúng được cập nhập lên latest version các bạn nhé!
Nội dung của tập tin pom.xml của Maven Archetype project của mình sẽ như sau:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 |
<?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>3.1.1</version> <relativePath /> <!-- lookup parent from repository --> </parent> <groupId>com.huongdanjava</groupId> <artifactId>clean-architecture-example</artifactId> <version>1.0-SNAPSHOT</version> <packaging>pom</packaging> <modules> <module>rest</module> <module>use-cases</module> <module>db</module> <module>entities</module> <module>configuration</module> </modules> <dependencyManagement> <dependencies> <dependency> <groupId>com.huongdanjava</groupId> <artifactId>entities</artifactId> <version>1.0-SNAPSHOT</version> </dependency> <dependency> <groupId>com.huongdanjava</groupId> <artifactId>use-cases</artifactId> <version>1.0-SNAPSHOT</version> </dependency> <dependency> <groupId>com.huongdanjava</groupId> <artifactId>db</artifactId> <version>1.0-SNAPSHOT</version> </dependency> <dependency> <groupId>com.huongdanjava</groupId> <artifactId>rest</artifactId> <version>1.0-SNAPSHOT</version> </dependency> <dependency> <groupId>org.hibernate</groupId> <artifactId>hibernate-core</artifactId> <version>6.2.5.Final</version> </dependency> </dependencies> </dependencyManagement> </project> |
Chúng ta sẽ sử dụng các placeholder ${groupId}, ${artifactId} và ${version} để thay thế cho thông tin groupId, artifactId và version được định nghĩa ở trên để khi generate project từ Maven Archetype project của chúng ta, các thông tin này được lấy từ input của người dùng:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 |
<?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> ... <groupId>${groupId}</groupId> <artifactId>${artifactId}</artifactId> <version>${version}</version> <packaging>pom</packaging> ... <dependencyManagement> <dependencies> <dependency> <groupId>${groupId}</groupId> <artifactId>entities</artifactId> <version>${version}</version> </dependency> <dependency> <groupId>${groupId}</groupId> <artifactId>use-cases</artifactId> <version>${version}</version> </dependency> <dependency> <groupId>${groupId}</groupId> <artifactId>db</artifactId> <version>${version}</version> </dependency> <dependency> <groupId>${groupId}</groupId> <artifactId>rest</artifactId> <version>${version}</version> </dependency> ... </dependencies> </dependencyManagement> </project> |
Tiếp theo, chúng ta sẽ copy các thư mục module từ clean-architecture-example project vào thư mục src/main/resources/archetype-resources của Maven Archetype project.
Kết quả như sau:
Để các module được generate như chúng ta mong muốn giống project clean-architecture-example, chúng ta cần phải chỉnh sửa một xí nội dung của các thư mục module.
Cụ thể, cho module configuration, trong tập tin pom.xml của module này, chúng ta sẽ sử dụng các placeholder ${groupId}, ${rootArtifactId} và ${version} để thay thế cho các thông tin về groupId, artifacId và version của parent và các module dependencies. Giá trị của placeholder ${rootArtifactId} sẽ là giá trị artifactId mà người dùng input các bạn nhé!
Nội dung của tập tin pom.xml trong thư mục configuration sẽ như sau:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 |
<?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <parent> <groupId>${groupId}</groupId> <artifactId>${rootArtifactId}</artifactId> <version>${version}</version> </parent> <modelVersion>4.0.0</modelVersion> <artifactId>configuration</artifactId> <dependencies> <dependency> <groupId>${groupId}</groupId> <artifactId>use-cases</artifactId> </dependency> <dependency> <groupId>${groupId}</groupId> <artifactId>db</artifactId> </dependency> <dependency> <groupId>${groupId}</groupId> <artifactId>rest</artifactId> </dependency> ... </dependencies> ... </project> |
Cho class Application, chúng ta sẽ move nó về thư mục /src/main/java và thay thế package name sử dụng placeholder ${package} như sau:
1 2 3 4 5 6 7 8 9 10 11 12 |
package ${package}; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; @SpringBootApplication public class Application { public static void main(String[] args) { SpringApplication.run(Application.class, args); } } |
Vì class UseCaseConfiguration nằm trong 1 sub-package nên chúng ta sẽ move class này về thư mục src/main/java/configuration và chỉnh sửa nội dung của nó như sau:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 |
package ${package}.configuration; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import ${package}.db.StudentAdapterImpl; import ${package}.usecases.adapter.StudentAdapter; import ${package}.usecases.student.FindStudentByNameUseCase; @Configuration public class UseCaseConfiguration { @Bean FindStudentByNameUseCase findStudentByNameUseCase(StudentAdapter studentAdapter) { return new FindStudentByNameUseCase(studentAdapter); } @Bean StudentAdapter studentAdapter() { return new StudentAdapterImpl(); } } |
Các bạn hãy để ý là mình cũng đã thay thế placeholder ${package} trong các dòng import để khi generate project, thông tin package sẽ được lấy từ input người dùng vào.
Cho các module còn lại, các bạn cũng hãy làm tương tự nhé!
Bước cuối cùng mà chúng ta cần làm là cấu hình tập tin archetype-metadata.xml nằm trong thư mục src/main/resources/META-INF/maven để include tất cả các tập tin, thư mục cần thiết khi generate Maven project sử dụng Maven Archetype project của chúng ta.
Chúng ta sẽ sử dụng tag <modules> cùng với các tag <module> để include các thư mục module vào project trong tập tin archetype-metadata.xml, cụ thể như sau:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 |
<archetype-descriptor xmlns="http://maven.apache.org/plugins/maven-archetype-plugin/archetype-descriptor/1.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/plugins/maven-archetype-plugin/archetype-descriptor/1.0.0 http://maven.apache.org/xsd/archetype-descriptor-1.0.0.xsd" name="${artifactId}"> <modules> <module dir="configuration"> <fileSets> <fileSet filtered="true" packaged="true"> <directory>src/main/java</directory> </fileSet> <fileSet filtered="true"> <directory>src/main/resources</directory> </fileSet> </fileSets> </module> <module dir="db"> <fileSets> <fileSet filtered="true" packaged="true"> <directory>src/main/java</directory> </fileSet> </fileSets> </module> <module dir="entities"> <fileSets> <fileSet filtered="true" packaged="true"> <directory>src/main/java</directory> </fileSet> </fileSets> </module> <module dir="rest"> <fileSets> <fileSet filtered="true" packaged="true"> <directory>src/main/java</directory> </fileSet> </fileSets> </module> <module dir="use-cases"> <fileSets> <fileSet filtered="true" packaged="true"> <directory>src/main/java</directory> </fileSet> </fileSets> </module> </modules> </archetype-descriptor> |
Như các bạn thấy, mình đã định nghĩa cho mỗi module trong project của chúng ta sử dụng một tag <module>. Trong mỗi tag <module>, chúng ta định nghĩa các <fileSets> để copy các tập tin thư mục trong từng module theo như chúng ta muốn như khi chúng ta tạo Maven Archetype project cho những Maven project bình thường.
Đến đây thì chúng ta đã hoàn thành việc cấu hình Maven Archetype cho Maven multi-module project rồi đó các bạn!
Hãy chạy “mvn clean install” trong thư mục root của project rồi import project basic-project trong thư mục
target/test-classes/projects/it-basic/project/ vào một IDE nào đó, các bạn sẽ thấy kết quả như sau: