Springboot+Maven多模块项目开发
前言
1.多模块项目的好处:
- 代码复用
一个后端项目的entity、dao、service代码需要用到前端服务,还需要用到后台管理,通过多模块可实现复用
- 减少build时间
只需要build改动到的模块
- 模块化代码不容易造成版本冲突
2.示例结构:
- Parent:
pom项目
作用:1.聚合子模块,自动管理子模块打包顺序等;2.进行总的依赖库版本管理
特别:不需要单独运行,没有启动类
- Common:
公共部分功能且无需单独运行的jar模块
作用:提取出的公共功能模块,被其他子模块依赖使用
特别:不需要单独运行,没有启动类
- ModuleOne:
业务功能需要单独运行的jar模块
作用:某一业务的运行模块,比如前端API服务
特别:需要单独运行,有启动类
- ModuleTwo:
业务功能需要单独运行的jar模块
作用:某一业务的运行模块,比如后端管理系统
特别:需要单独运行,有启动类
示例项目建设
示例代码仓库:
https://gitee.com/x-shungeer/hello-cloud/tree/master/00%20mutil-module-demo
Parent项目
利用Spring Initializr建立基于Maven的项目
Parent项目能够聚合子模块,聚合后能够批处理所有子模块,比如:
ModuleOne模块依赖Common模块,Maven打包ModuleOne时,需要先install模块Common,否则就会报错,当ModuleOne模块依赖的模块很多时,此步骤就显得耗时耗力了。使用Parent项目能够自动处理这个问题。
Spring Initializr脚手架URL:
1.https://start.spring.io
2.httpw://start.aliyun.com
针对Parent项目的pom.xml:
<?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>
<!-- 指定该项目打包类型。pom 表示这是一个父项目(也称为聚合项目),它通常不包含可执行的代码,而是用于管理和组织多个子模块 -->
<packaging>pom</packaging>
<parent>
<!-- 源头是spring-boot-dependencies,定义了当前SpringBoot版本能用到的所有依赖及其适配的版本号 -->
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.7.6</version>
<!-- 指定父模块pom.xml相对位置,若父模块pom.xml与子模块文件夹属于同一目录,则不用指定该值 -->
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>com.study.hello</groupId>
<artifactId>mutil-module-demo</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>00 mutil-module-demo</name>
<description>00 mutil-module-demo</description>
<!-- 父模块的properties也是向下继承的 -->
<properties>
<java.version>11</java.version>
<project.encode>UTF-8</project.encode>
<project.build.sourceEncoding>${project.encode}</project.build.sourceEncoding>
<project.reporting.outputEncoding>${project.encode}</project.reporting.outputEncoding>
</properties>
<!-- 父模块依赖,被所有子模块共用的 -->
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
<!-- 依赖版本管理,管理子模块对应依赖的版本 -->
<dependencyManagement>
<dependencies>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
<version>1.2.73</version>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.18.24</version>
<scope>provided</scope>
</dependency>
</dependencies>
</dependencyManagement>
<!-- 只有声明在父模块pom.xml文件的modules中的子模块,才会被构建 -->
<modules>
<module>module-common</module>
<module>module-one</module>
<module>module-two</module>
</modules>
</project>
Common模块
pom.xml:
<?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>com.study.hello</groupId>
<artifactId>mutil-module-demo</artifactId>
<version>0.0.1-SNAPSHOT</version>
</parent>
<groupId>com.study.hello</groupId>
<artifactId>module-common</artifactId>
<!-- 子模块可以不声明version,这样该模块直接继承父模块版本号,其余子模块同理 -->
<version>0.0.1-SNAPSHOT</version>
<name>module-common</name>
<description>module-common</description>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
<exclusions>
<exclusion>
<groupId>org.junit.vintage</groupId>
<artifactId>junit-vintage-engine</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</dependency>
</dependencies>
</project>
ModuleOne模块
pom.xml:
<?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>com.study.hello</groupId>
<artifactId>mutil-module-demo</artifactId>
<version>0.0.1-SNAPSHOT</version>
</parent>
<groupId>com.study.hello</groupId>
<artifactId>module-one</artifactId>
<!-- 子模块可以不声明version,这样该模块直接继承父模块版本号,其余子模块同理 -->
<version>0.0.1-SNAPSHOT</version>
<name>module-one</name>
<description>module-one</description>
<dependencies>
<dependency>
<groupId>com.study.hello</groupId>
<artifactId>module-common</artifactId>
<version>0.0.1-SNAPSHOT</version>
</dependency>
<!-- 由于在父模块dependencyManagement中声明了这个依赖的版本,因此子模块引入这个依赖不需要声明版本号,构建引入时会自动向上查找父模块dependencyManagement中对应依赖的版本 -->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
</dependency>
<!--注意:这个地方的junit是没有版本号的,
maven会自动的向上找,找到<dependencyManagerment>标签并使用它里面声明的依赖的版本号-->
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<configuration>
<!-- 指定打包时 jar的输出位置 -->
<!-- <outputDirectory>../target</outputDirectory> -->
<!--<mainClass>com.study.hello.ModuleCommonApplication</mainClass>-->
<!--<classifier>exec</classifier>-->
</configuration>
<executions>
<execution>
<goals>
<!-- 可以把依赖的包都打包到生成的jar包中 -->
<!-- <goal>repackage</goal> -->
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
</project>
特别说明
1.Parent项目继承自
spring-boot-starter-parent
,源头是spring-boot-dependencies
,定义了当前SpringBoot版本能用到的所有依赖及其适配的版本号。此处也可以不继承spring-boot-starter-parent
,而是在标签<dependencyManagement>
内定义子模块用到的所有Springboot的依赖版本,如下述代码所示。
2.
<relativePath/>
标签可以指定父模块pom.xml文件所在的相对路径。基准目录是:子模块文件夹与父模块的pom.xml所在的同一目录,此时可以不指定标签的值,其他情况下需要根据此基准目录指定相对目录。例如父模块的pom.xml文件位于子模块文件夹的上两级目录,此时的标签值为:../../pom.xml
3.
<modules>
和<parent>
两个标签的组合拳:<parent>
标签声明继承,主要继承属性、依赖等等父模块的属性,而父模块中的<modules>
是指定哪些子模块会随着该父模块一起被构建。所以,如果在项目中存在用于测试的子模块需要继承父模块,但是又不希望这些模块最后被构建,就可以在父模块中的<modules>
删除这些子模块的声明。
4.
<dependencies>
管理所有子模块的共用依赖,也可以在此指定当前模块的依赖包,父模块<dependencies>
所定义的依赖包都会被子模块所继承。
5.
<dependencyManagement>
管理子模块不共用的依赖库版本。这样的好处是:当模块增多时,不用一个个去修改一些不共用的依赖库版本,在<dependencyManagement>
中修改即可。当父模块的pom.xml定义好<dependencyManagement>
依赖库版本后,子模块在<dependencies>
中直接指定依赖库名字,而不用指定版本,Maven会自动去父模块的<dependencyManagement>
中定位。当然,所某个子模块不想使用父模块<dependencyManagement>
指定的依赖库版本,子模块可以在<dependencies>
中指定自己的版本。
6.Common模块不指定
<build>
标签,否则ModuleA模块和ModuleB模块build时会提示错误:Unable to find main class
。这是因为spring-boot-maven-plugin打成的jar包可以运行,但是不能被其他工程依赖
。此外Common模块不指定@SpringBootTest
,否则会提示错误:java.lang.IllegalStateException: Unable to find a @SpringBootConfiguration, you need to use @ContextConfiguration or @SpringBootTest(classes=...) with your test
<dependencyManagement>
内定义子模块用到的所有Springboot的依赖版本的代码:
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-dependencies</artifactId>
<version>2.7.6.RELEASE</version>
<!--<type>pom</type>配合<scope>import</scope>标签可以额外引入其他的pom文件中的<dependencyManagement>内容,解决了maven单继承的问题。-->
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
参考:
1、https://blog.csdn.net/m0_71777195/article/details/131592022
2、https://blog.csdn.net/qq_40925189/article/details/103842208
原文地址:https://blog.csdn.net/xys206006/article/details/140624871
免责声明:本站文章内容转载自网络资源,如本站内容侵犯了原著者的合法权益,可联系本站删除。更多内容请关注自学内容网(zxcms.com)!