一,分模块思路
分模块开发就是将我们一整个完整的项目拆解为多个模块,方便团队开发。如下图所示:
每一个模块都对应一个单独的pom文件,然后在使用的时候我们直接把每个模块当成外部jar包,需要使用的时候直接在自己的pom文件中导入对应的坐标即可。
在拆解完毕后,需要删除跟这个模块无关的配置文件,无关的依赖,只留下与该模块所需的相关依赖。
注意:在拆解好模块后需要在生命周期中install一下上传到我们本地仓库中,如果存在私服就deploy上去才能正常使用这些拆解的模块。
二,Maven聚合
假设我们将一个大模块拆解为多个小模块,并且A--依赖----->B--依赖----->C----依赖--->D
假设C模块更新了并且install到了本地仓库,此时会其他模块并不知道C模块更新了,可能会导致项目崩溃。
解决办法:通过聚合,只要模块中任意一个模块更新了,其他模块都一起更新。
聚合方法:创建一个新模块,里面只有pom文件,用来管理全部模块。
如下图:
pom文件主要标签
<?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>com.normaling</groupId>
<artifactId>BlogManager-parent</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>pom</packaging>
<!-- 声明子模块列表 -->
<modules>
<module>ManagerModel</module>
</modules>
</project>
假设在模块中存在A--依赖----->B--依赖----->C----依赖--->D这种关系,那么我们通过模块进行编译的时候,会按照A,B,C,D这个顺序进行编译。如果不是这种线性依赖,那么就会按照我们配置的顺序进行编译。
packagin标签的值有:
- pom表明这个工程是用于构建管理的。
- jar表明这个是打jar包,资源包
- war表面这个是打war包,网页相关的
三,继承
如下图,当我们的service模块使用的是5.1.9版本,dao模块使用的是5.2.0版本,如果两个版本的spring-context不兼容,那就可能会导致项目崩溃。
解决方法:在用于构建管理的那个模块中选择指定版本的spring-context版本,在其他模块中只指定要用这个模块,但不指定模块具体版本。
这个就是继承。
使用方法:
-
在父工程中导入这个项目需要使用的所有依赖
<?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>com.normaling</groupId> <artifactId>BlogManager-parent</artifactId> <version>0.0.1-SNAPSHOT</version> <packaging>pom</packaging> <!-- 声明子模块列表 --> <modules> <module>ManagerModel</module> </modules> <dependencyManagement> <dependencies> <!--需要统一管理的模块坐标--> </dependencies> </dependencyManagement> <!-- 插件管理 --> <build> <pluginManagement> <plugins> <!--需要统一管理的插件坐标--> </plugins> </pluginManagement> </build> </project> -
在子工程中定义该工程的父工程的坐标
<?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>com.normaling</groupId> <artifactId>BlogManager-parent</artifactId> <version>0.0.1-SNAPSHOT</version> <!--父工程的相对路径的pom文件--> <relativePath>../pom.xml</relativePath> </parent> <artifactId>ManagerModel</artifactId> <properties> <maven.compiler.source>17</maven.compiler.source> <maven.compiler.target>17</maven.compiler.target> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> </properties> <dependencies> <!--子模块需要使用的依赖--> </dependencies> <!-- 插件管理 --> <!-- 我们在子模块导入时如果需要单独为子模块配置,就直接在子模块显示配置即可,配置会覆盖的--> <build> <plugins> <!-- 编译插件 --> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-compiler-plugin</artifactId> </plugin> <!-- Spring Boot 打包插件 --> <plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> <configuration> <skip>false</skip><!--跳过打包,这里需要false,因为子模块实际有内容--> </configuration> </plugin> </plugins> </build> </project>注意:
- 删除子工程的
groupId标签和version。因为子工程和父工程是同一个组织,同一个版本。 - 删除子工程所有的依赖的版本
version标签和插件的version,统一交给父工程管理。 - 我们自己拆好的模块记得也要导入到依赖管理之中进行管理。
- 删除子工程的
子工程可以继承的标签如下:
四,属性
通过上述的继承和聚合之后,我们将整个项目的依赖管理全部集中到了父工程的pom文件中,假设我们要对某一特定依赖的版本进行更新,可能需要对其他的模块统一进行更新,但是一个个找就可能会出现漏掉更新的模块。
解决方法就是:通过在maven中设置属性,用属性存储具体的版本信息,将所有的依赖使用属性统一进行管理。
属性的类别:
-
自定义属性
作用:等同于java中的变量,方便不同依赖之间的统一维护。
使用方法:在父工程中定义
<properties></properties><!--定义自定义属性--> <properties> <!--命名方法:模块名.version--> <spring.version>spring模块的版本</spring.version> <junit.version></junit.version> </properties>调用方法:
${自定义属性名}<dependency> <groupId>org.springframework</groupId> <artifactId>spring-context</artifactId> <version>${spring.version}</version> </dependency> -
内置属性
作用:使用maven内置属性,比如说在父工程中,父工程内部的坐标标签的值]
调用方法:
${basedir} <!--父工程坐标的version标签值--> ${version} -
Setting属性
作用:使用maven配置文件
setting.xml中的标签属性,用于动态配置调用方法:
${settings.属性名} -
Java系统属性
作用:读取Java系统属性
使用方法:
${系统属性名} -
环境变量
作用:使用maven配置文件setting.xml中的标签属性,用于动态配置
调用方法:
${env.环境属性名}
系统属性查询方式和环境变量属性查询方法:
mvn help:system
填入等号前面的属性名即可获得属性值。
五,版本命名
Maven工程版本分为两个版本(每个公司定义的版本号都有区别,实际按照规则要求命名即可)
-
SNAPSHOT(快照版本:maven工程版本默认就是这个)
项目开发过程中,为方便团队成员合作,解决模块间相互依赖和时间更新的问题,开发者对每个模块进行构建的时候,输出的临时版本,快照版本UI随着开发的进展不断更新
-
RELEASE(发布版本)
项目开发到进入阶段里程碑后,向团队外部发布较为稳定的版本,这种版本对应的构建文件是稳定的,即便进行功能的后续开发,也不会改变当前发布版本的内容
工程版本号,约定规范 <主版本>.<次版本>.<增量版本>.<里程碑版本>,例如5.1.9.RELEASE
- 主版本:表示项目重大架构的变更,如:spring5和springboot2相较于spring4和springboot1的迭代
- 次版本:表示有较大的功能增加和变化,或者全面系统地修复漏洞
- 增量版本:表示有重大漏洞的修复
- 里程碑版本:表明一个版本的里程碑(版本内部),这样的版本同下一个正式版本相比,相对来说不是很稳定,需要更多的测试
六,资源配置
我们在Spring工程里面的yaml配置文件编写的dbc.driver、jdbc.url等,也可以通过maven直接配到pom.xml中进行统一的配置。
这个就是资源配置。
使用方法:
-
在pom.xml文件中:
<properties> <jdbc.url>jdbc:mysql://127.0.0.1:3306/srb</jdbc.url> <jdbc.username>root</jdbc.username> </properties> <build> <!--配置资源文件对应的信息--> <resources> <resource> <!--路径,一定要对,${project.basedir}项目路径为maven自带属性,方便配置所有的模块。--> <directory>${project.basedir}/src/main/resources</directory> <!--参与过滤,false不解析,打包的时候就是配的值(${jdbc.url})--> <filtering>true</filtering> </resource> </resources> <!--测试资源,路径不是main,是test--> <testResources> <testResource> <directory>${project.basedir}/src/test/resources</directory> <filtering>true</filtering> </testResource> </testResources> </build> -
在原始yaml配置文件中:
jdbc: url: ${jdbc.url} username: ${jdbc.username}不推荐这种写法,了解即可。
七,跳过测试
跳过测试有三种方法:
-
idea自带选项点击即可
-
使用maven命令跳过测试
mvn 指定maven生命周期 -D skipTests -
配置pom文件来跳过测试
<build> <pluginManagement> <plugins> <!--配置跳过测试--> <plugin> <!--测试插件的坐标--> <groupId>org.apache.maven</groupId> <artifactId>maven-surefire-plugin</artifactId> <version>你测试插件的版本,具体去看maven仓库查就行了</version> <configuration> <!--设置整个项目都跳过测试--> <skipTests>true</skipTests> <!--包含指定测试用例要进行测试--> <includes> <!--**代表任意包--> <include>**/UserServiceTest.java</include> </includes> <!--排除指定测试用例要进行测试--> <excludes> <exclude> </exclude> </excludes> </configuration> </plugin> </plugins> </pluginManagement> </build>
八,外部下载的jar包安装到本地仓库
在写的时候我发现有时候我们需要外接类似阿里云OSS的sdk的jar包,但是如果你直接去写坐标是没用的,因为外部仓库是不存在这个jar包的,所有可以采用先下载这个jar包然后安装到本地即可。当然安装到私服也是可以的。
mvn install:install-file
-Dfile=spring.jar //jar包名称
-Dartifactld=spring //jar包源项目的artifactid
-DgroupId=com.fpl //jar包源项目的groupid
-Dversion=1.0-SNAPSHOT //jar包源项目的version
-Dpackaging=jar
九,拆分项目注意要点
-
父模块
<?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>com.normaling</groupId> <artifactId>BlogManager-parent</artifactId> <version>0.0.1-SNAPSHOT</version> <packaging>pom</packaging> <!-- 声明子模块列表 --> <modules> <module>ManagerModel</module> </modules> <!-- 统一属性管理 --> <properties> <java.version>17</java.version> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding> <spring-boot.version>3.0.2</spring-boot.version> <mybatis.version>3.0.0</mybatis.version> <mysql.version>8.0.33</mysql.version> <lombok.version>1.18.26</lombok.version> </properties> <dependencyManagement> <dependencies> <!-- Spring Boot BOM --> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-dependencies</artifactId> <version>${spring-boot.version}</version> <type>pom</type> <scope>import</scope> </dependency> <!--lombok管理--> <dependency> <groupId>org.projectlombok</groupId> <artifactId>lombok</artifactId> <version>${lombok.version}</version> <optional>true</optional> </dependency> <!-- MyBatis --> <dependency> <groupId>org.mybatis.spring.boot</groupId> <artifactId>mybatis-spring-boot-starter</artifactId> <version>${mybatis.version}</version> </dependency> <!-- MySQL --> <dependency> <groupId>com.mysql</groupId> <artifactId>mysql-connector-j</artifactId> <version>${mysql.version}</version> <scope>runtime</scope> </dependency> </dependencies> </dependencyManagement> <!-- 插件管理 --> <build> <pluginManagement> <plugins> <!-- 编译插件 --> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-compiler-plugin</artifactId> <configuration> <source>${java.version}</source> <target>${java.version}</target> <encoding>${project.build.sourceEncoding}</encoding> </configuration> </plugin> <!-- Spring Boot 打包插件 --> <plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> <version>${spring-boot.version}</version> <configuration> <skip>true</skip> <!-- 默认跳过,子模块按需启用 --> </configuration> </plugin> </plugins> </pluginManagement> </build> </project> -
子模块
<?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>com.normaling</groupId> <artifactId>BlogManager-parent</artifactId> <version>0.0.1-SNAPSHOT</version> <!--父工程的相对路径的pom文件--> <relativePath>../pom.xml</relativePath> </parent> <artifactId>ManagerModel</artifactId> <dependencies> <!--SpringWeb依赖--> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <!--lombok管理--> <dependency> <groupId>org.projectlombok</groupId> <artifactId>lombok</artifactId> <optional>true</optional> </dependency> <!-- MyBatis --> <dependency> <groupId>org.mybatis.spring.boot</groupId> <artifactId>mybatis-spring-boot-starter</artifactId> </dependency> <!-- MySQL --> <dependency> <groupId>com.mysql</groupId> <artifactId>mysql-connector-j</artifactId> <scope>runtime</scope> </dependency> </dependencies> <!-- 插件管理 --> <build> <plugins> <!-- 编译插件 --> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-compiler-plugin</artifactId> </plugin> <!-- Spring Boot 打包插件 --> <plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> <configuration> <skip>false</skip> </configuration> </plugin> </plugins> </build> </project> -
注意要点:
-
我们父模块的SpringBoot依赖管理有两种方式
特性 <parent>继承方式<dependencyManagement>+ BOM 导入方式核心作用 继承父 POM 的配置(依赖、插件、属性等) 仅导入依赖版本管理,不继承其他配置 灵活性 强制继承所有配置,可能与其他父 POM 冲突 更灵活,允许项目有自己的父 POM 适用场景 单模块项目或明确需要 Spring Boot 作为父级的情况 多模块项目、已有自定义父 POM 的项目 依赖版本管理 自动继承所有 Spring Boot 管理的依赖版本 需显式导入 BOM,但版本仍由 Spring Boot 统一管理 上述讲的是parent继承方式,但SpringBoot已经改成Bom导入方式了,所以我们这边也改成这样
-
Bom导入后我们父依赖不需要显示导入SpringBootWeb依赖,因为它里面已经有了,我们只需要在子模块中引入即可
-
关于Maven插件中skip配置,在父模块需要开启,在子模块中统一禁用它
-
-
在分模块后,例如Mybatis的mapper文件,一般每个模块都有一个的,但是这样包扫描的时候会扫描不到,我们需要在pom里面
-
在父模块依赖管理都管理这些子模块
-
在子模块中启动类那个模块依赖这些所有的子模块
-