JavaJava 多模块构建和弊端
MeteorCat在 Java 项目开发中, 多模块(Multi-Module) 是基于 Maven|Gradle 等构建工具实现的项目结构设计模式,
主要核心是将一个大型项目拆分为多个功能独立和职责单一的子模块(Module), 通过构建工具管理模块间的依赖和打包流程.
看起来很理想, 将代码合并在共同项目下复用大量的功能逻辑从而避免重复开发, 可以减少大项目之后大量冗余代码.
但是实际操作问题点很多, 最终在大量现实问题当中只能直接放弃 Java 的多项目管理, 这里说下主要踩坑的点:
-
无法单独项目独立: 项目都是寄放在同个 git 仓库, 也就是代表 clone 就能把所有业务秘密全导出(加密哈希和字段检验方式)
-
循环交叉依赖: 有时候业务很容易出现双方模块做交叉依赖, B 项目交叉用到 A 项目的验证库, C 项目也依赖 A 项目, 升级都要跟随升级
-
模块编译复杂度提升: 因为归到同个 git 库(比如区分 user/pay 等业务), 某个业务增加新业务提交上去一变动就要全部检测编译
-
业务堆叠在相同版本库: 所有业务都集中在一个版本库, 日积月累所有人提交版本导致堆叠在一起, 时间长了版本拉取时间也十分长
-
新人入职的时候无法上手: 所有库交叉在通个版本新人上手的时候采用 IDEA 全局搜索指定函数方法都要很久(文件太多)
后来发现 Java 项目多模块化只能作为系统通用组件模块开发, 涉及业务的情况迭代太快导致混合起来版本号疯狂暴涨
这里如果是后端尽量采用 Maven 管理, 实际上 Gradle 管理非常混乱, 破坏性更新太多了很不好管理做持久维护.
提供个简单的多模块样例:
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 58 59 60 61 62 63 64 65 66 67 68
| <?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 https://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion>
<groupId>io.meteorcat.services</groupId> <artifactId>bom</artifactId> <name>service-bom</name> <version>1.0-SNAPSHOT</version> <packaging>pom</packaging>
<properties> <compiler-plugin.version>3.14.0</compiler-plugin.version> <maven.compiler.release>17</maven.compiler.release> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding> </properties>
<modules> <module>api</module> </modules>
<dependencyManagement> </dependencyManagement>
<repositories> <repository> <id>ali-yun-central</id> <url>https://maven.aliyun.com/repository/central</url> <releases> <enabled>true</enabled> </releases> <snapshots> <enabled>true</enabled> </snapshots> </repository> </repositories>
<pluginRepositories>
<pluginRepository> <id>ali-yun-plugin-public</id> <url>https://maven.aliyun.com/repository/public</url> <releases> <enabled>true</enabled> </releases> <snapshots> <enabled>true</enabled> </snapshots> </pluginRepository> </pluginRepositories>
<build> </build> </project>
|
之后其他的子配置如下设置, 其实可以直接继承上级设置:
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
| <?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 https://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion>
<parent> <groupId>io.meteorcat.services</groupId> <artifactId>bom</artifactId> <version>1.0-SNAPSHOT</version> <relativePath>../pom.xml</relativePath> </parent>
<artifactId>api</artifactId> <name>service-api</name> <version>1.0-SNAPSHOT</version> <packaging>jar</packaging>
<properties> </properties>
<dependencies> </dependencies>
</project>
|
这样就是通用的 Maven 多项目模板, 其实和常规的项目差不多, 这里以 Quarkus 项目加载:
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 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171
| <?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 https://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion>
<groupId>io.meteorcat.services</groupId> <artifactId>bom</artifactId> <name>service-bom</name> <version>1.0-SNAPSHOT</version> <packaging>pom</packaging>
<properties> <compiler-plugin.version>3.14.0</compiler-plugin.version> <maven.compiler.release>17</maven.compiler.release> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<quarkus.platform.artifact-id>quarkus-bom</quarkus.platform.artifact-id> <quarkus.platform.group-id>io.quarkus.platform</quarkus.platform.group-id> <quarkus.platform.version>3.27.0</quarkus.platform.version> <skipITs>true</skipITs> <surefire-plugin.version>3.5.3</surefire-plugin.version> </properties>
<modules> <module>api</module> </modules>
<dependencyManagement> <dependencies> <dependency> <groupId>${quarkus.platform.group-id}</groupId> <artifactId>${quarkus.platform.artifact-id}</artifactId> <version>${quarkus.platform.version}</version> <type>pom</type> <scope>import</scope> </dependency> </dependencies> </dependencyManagement>
<repositories> <repository> <id>ali-yun-central</id> <url>https://maven.aliyun.com/repository/central</url> <releases> <enabled>true</enabled> </releases> <snapshots> <enabled>true</enabled> </snapshots> </repository> </repositories>
<pluginRepositories>
<pluginRepository> <id>ali-yun-plugin-public</id> <url>https://maven.aliyun.com/repository/public</url> <releases> <enabled>true</enabled> </releases> <snapshots> <enabled>true</enabled> </snapshots> </pluginRepository> </pluginRepositories>
<build> <plugins> <plugin> <groupId>${quarkus.platform.group-id}</groupId> <artifactId>quarkus-maven-plugin</artifactId> <version>${quarkus.platform.version}</version> <extensions>true</extensions> <executions> <execution> <goals> <goal>build</goal> <goal>generate-code</goal> <goal>generate-code-tests</goal> <goal>native-image-agent</goal> </goals> </execution> </executions> </plugin>
<plugin> <artifactId>maven-compiler-plugin</artifactId> <version>${compiler-plugin.version}</version> <configuration> <parameters>true</parameters> </configuration> </plugin>
<plugin> <artifactId>maven-surefire-plugin</artifactId> <version>${surefire-plugin.version}</version> <configuration> <argLine>--add-opens java.base/java.lang=ALL-UNNAMED</argLine> <systemPropertyVariables> <java.util.logging.manager>org.jboss.logmanager.LogManager</java.util.logging.manager> <maven.home>${maven.home}</maven.home> </systemPropertyVariables> </configuration> </plugin>
<plugin> <artifactId>maven-failsafe-plugin</artifactId> <version>${surefire-plugin.version}</version> <executions> <execution> <goals> <goal>integration-test</goal> <goal>verify</goal> </goals> </execution> </executions> <configuration> <argLine>--add-opens java.base/java.lang=ALL-UNNAMED</argLine> <systemPropertyVariables> <native.image.path>${project.build.directory}/${project.build.finalName}-runner </native.image.path> <java.util.logging.manager>org.jboss.logmanager.LogManager</java.util.logging.manager> <maven.home>${maven.home}</maven.home> </systemPropertyVariables> </configuration> </plugin>
</plugins> </build>
<profiles> <profile> <id>native</id> <activation> <property> <name>native</name> </property> </activation> <properties> <quarkus.package.jar.enabled>false</quarkus.package.jar.enabled> <skipITs>false</skipITs> <quarkus.native.enabled>true</quarkus.native.enabled> </properties> </profile> </profiles> </project>
|
这里子项目如下, 也是直接不过因为上级声明了 dependencyManagement 所以不需要设置指定版本:
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
| <?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 https://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion>
<parent> <groupId>io.meteorcat.services</groupId> <artifactId>bom</artifactId> <version>1.0-SNAPSHOT</version> <relativePath>../pom.xml</relativePath> </parent>
<artifactId>api</artifactId> <name>service-api</name> <version>1.0-SNAPSHOT</version> <packaging>jar</packaging>
<properties> </properties>
<dependencies> <dependency> <groupId>io.quarkus</groupId> <artifactId>quarkus-arc</artifactId> </dependency>
<dependency> <groupId>io.quarkus</groupId> <artifactId>quarkus-junit5</artifactId> <scope>test</scope> </dependency>
<dependency> <groupId>io.rest-assured</groupId> <artifactId>rest-assured</artifactId> <scope>test</scope> </dependency> </dependencies>
</project>
|