Skip to content

​


Maven 官网:https://maven.apache.org/

Maven 安装 ​

Maven 3.9.4 安装包 ​

安装包: https://pan.baidu.com/s/1hNC1vSXbkvOGnHNJS0SqaQ?pwd=3tn6 提取码: 3tn6 ​

安装路径不要带有中文或者空格 ​

解压安装包 ​

alt text

(1)bin 目录 : 存放的是可执行命令。(mvn 命令重点关注) ​

(2)conf 目录 :存放 Maven 的配置文件。(settings.xml 配置文件后期需要修改) ​

(3)lib 目录 :存放 Maven 依赖的 jar 包。(Maven 也是使用 java 开发的,所以它也依赖其他的 jar 包) ​

配置本地仓库 ​

(1)新一个目录命名为 mvn_repo_local(本地仓库,用来存储 jar 包) ​

(2)进入到 conf 目录下修改 settings.xml 配置文件 ​

使用超级记事本软件,打开 settings.xml 文件,定位到 53 行 ​

复制<localRepository>标签,粘贴到注释的外面(55 行) ​

复制之前新建的用来存储 jar 包的路径,替换掉<localRepository>标签体内容 ​

配置阿里云私服 ​

由于中央仓库在国外,所以下载 jar 包速度可能比较慢,而阿里公司提供了一个远程仓库,里面基本也都有开源项目的 jar 包 ​

进入到 conf 目录下修改 settings.xml 配置文件 ​

(1)使用超级记事本软件,打开 settings.xml 文件,定位到 160 行左右 ​

(2)在<mirrors>标签下为其添加子标签<mirror>,内容如下 ​

xml
<mirror>
    <id>alimaven</id>
    <name>aliyun maven</name>
    <url>http://maven.aliyun.com/nexus/content/groups/public/</url>
    <mirrorOf>central</mirrorOf>
</mirror>

配置环境变量 ​

(1)在系统变量处新建一个变量 MAVEN_HOME。 MAVEN_HOME 环境变量的值,设置为 maven 的解压安装目录 ​ ​

​

(2) 在 Path 中进行配置。 PATH 环境变量的值,设置为:%MAVEN_HOME%\bin​ ​

​

(3)cmd 测试 ​

输入指令: mvn - v ​

关联 JDK 版本(可选) ​

进入到 conf 目录下修改 settings.xml 配置文件,在 <profiles> </profiles>中增加如下配置(以 JDK17 版本举例) ​

xml
<profile>
        <id>jdk-17</id>
        <activation>
                <activeByDefault>true</activeByDefault>
                <jdk>17</jdk>
        </activation>
        <properties>
                <maven.compiler.source>17</maven.compiler.source>
                <maven.compiler.target>17</maven.compiler.target>
                <maven.compiler.compilerVersion>17</maven.compiler.compilerVersion>
        </properties>
</profile>

解决 Maven 面板报红 ​


问题现象:Maven 项目中添加的依赖,未正确下载,造成右侧 Maven 面板中的依赖报红,再次 reload 重新加载也不会再下载 ​

产生原因:由于网络原因,依赖没有下载完整导致的,在 maven 仓库中生成了 xxx.lastUpdated 文件,该文件不删除,不会再重新下载 ​


解决方案 ​

(1)根据 maven 依赖的坐标,找到仓库中对应的 xxx.lastUpdated 文件,删除,删除之后重新加载项目即可 ​

(2)通过命令 (del /s *.lastUpdated) 批量递归删除指定目录下的 xxx.lastUpdated 文件,删除之后重新加载项目即可 ​

(3)重新加载依赖,依赖下载了之后,maven 面板可能还会报红,此时可以关闭 IDEA,重新打开 IDEA 加载此项目即可 ​

Maven 作用 ​

Maven 是一款用于管理和构建 Java 项目的工具,是 Apache 旗下的一个开源项目 ​

依赖管理 ​

方便快捷的管理项目依赖的资源(jar 包),避免版本冲突问题 ​

(1)使用 maven 前 ​

我们项目中要想使用某一个 jar 包,就需要把这个 jar 包从官方网站下载下来,然后再导入到项目中。然后在这个项目中,就可以使用这个 jar 包了 ​

(2)使用 maven 后 ​

当使用 maven 进行项目依赖(jar 包)管理,则很方便的可以解决这个问题。 我们只需要在 maven 项目的 pom.xml 文件中,添加一段如下图所示的配置即可实现 ​

(3)小结 ​

在 maven 项目的配置文件中,加入上面这么一段配置信息之后,maven 会自动的根据配置信息的描述,去下载对应的依赖。 然后在项目中,就可以直接使用了 ​

项目构建 ​

Maven 还提供了标准化的跨平台的自动化构建方式 ​

如上图所示我们开发了一套系统,代码需要进行编译、测试、打包、发布等过程,这些操作是所有项目中都需要做的,如果需要反复进行就显得特别麻烦,而 Maven 提供了一套简单的命令来完成项目构建 ​

通过 Maven 中的命令,就可以很方便的完成项目的编译(compile)、测试(test)、打包(package)、发布(deploy) 等操作 ​

而且这些操作都是跨平台的,也就是说无论你是 Windows 系统,还是 Linux 系统,还是 Mac 系统,这些命令都是支持的 ​

统一项目结构 ​

Maven 还提供了标准、统一的项目结构 ​

(1)未使用 Maven ​

由于 java 的开发工具呢,有很多,除了大家熟悉的 IDEA 以外,还有像早期的 Eclipse、MyEclipse。而不同的开发工具,创建出来的 java 项目的目录结构是存在差异的,那这就会出现一个问题 ​

Eclipse 创建的 java 项目,并不能直接导入 IDEA 中。 IDEA 创建的 java 项目,也没有办法直接导入到 Eclipse 中 ​

(2)使用 Maven ​

而如果我们使用了 Maven 这一款项目构建工具,它给我们提供了一套标准的 java 项目目录。如下所示 ​

也就意味着,无论我们使用的是什么开发工具,只要是基于 maven 构建的 java 项目,最终的目录结构都是相同的,如图所示。 那这样呢,我们使用 Eclipse、MyEclipse、IDEA 创建的 maven 项目,就可以在各个开发工具直接直接导入使用了,更加方便、快捷 ​

而在上面的 maven 项目的目录结构中,main 目录下存放的是项目的源代码,test 目录下存放的是项目的测试代码。 而无论是在 main 还是在 test 下,都有两个目录,一个是 java,用来存放源代码文件;另一个是 resources,用来存放配置文件 ​

Maven 介绍 ​

基本介绍 ​

Apache Maven 是一个项目管理和构建工具,它基于项目对象模型(Project Object Model , 简称: POM)的概念,通过一小段描述信息来管理项目的构建、报告和文档 ​

Maven 作用 ​

(1)方便的依赖管理 ​

(2)统一的项目结构 ​

(3)标准的项目构建流程 ​

Maven 模型 ​

(1)项目对象模型 (Project Object Model) ​

(2)依赖管理模型(Dependency) ​

(3)构建生命周期/阶段(Build lifecycle & phases) ​

(1)项目对象模型 (Project Object Model) ​

以上图中紫色框起来的部分,就是用来完成标准化构建流程 。当我们需要编译,Maven 提供了一个编译插件供我们使用;当我们需要打包,Maven 就提供了一个打包插件供我们使用等 ​

(2)依赖管理模型(Dependency) ​

以上图中紫色框起来的部分属于项目对象模型,就是将我们自己的项目抽象成一个对象模型,有自己专属的坐标,如下图所示是一个 Maven 项目: ​

坐标,就是资源(jar 包)的唯一标识,通过坐标可以定位到所需资源(jar 包)位置 ​

坐标的组成部分: ​

(1)groupId: 组织名 ​

(2)arfitactId: 模块名 ​

(3)Version: 版本号 ​

(3)构建生命周期/阶段(Build lifecycle & phases) ​

以上图中紫色框起来的部分属于依赖管理模型,是使用坐标来描述当前项目依赖哪些第三方 jar 包 ​

之前我们项目中需要 jar 包时,直接就把 jar 包复制到项目下的 lib 目录,而现在我们只需要在 pom.xml 中配置依赖的配置文件即可。 而这个依赖对应的 jar 包其实就在我们本地电脑上的 maven 仓库中 ​

如下图,就是老师本地的 maven 仓库中的 jar 文件: ​

Maven 仓库 ​

(1)本地仓库:自己计算机上的一个目录(用来存储 jar 包) ​

(2)中央仓库:由 Maven 团队维护的全球唯一的。仓库地址:https://repo1.maven.org/maven2/ ​

(3)远程仓库(私服):一般由公司团队搭建的私有仓库 ​

当项目中使用坐标引入对应依赖 jar 包后, ​

  • 首先会查找本地仓库中是否有对应的 jar 包

(1)如果有,则在项目直接引用 ​

(2)如果没有,则去中央仓库中下载对应的 jar 包到本地仓库 ​

  • 如果还可以搭建远程仓库(私服),将来 jar 包的查找顺序则变为: 本地仓库 --> 远程仓库--> 中央仓库

IDEA 集成 Maven ​

全局配置 ​

⚠️ 注意点:需要关闭项目,到创建项目界面中找到设置,完成相关配置 ​

配置编译版本 ​


创建 Maven 项目 ​

(1)创建一个空项目 ​


(2)配置 JDK 版本 ​


(3)创建模块 ​



项目结构 ​


pom 文件解读 ​

POM (Project Object Model) :指的是项目对象模型,用来描述当前的 maven 项目 ​

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 http://maven.apache.org/xsd/maven-4.0.0.xsd">

    <!--POM模型版本-->
    <modelVersion>4.0.0</modelVersion>

    <!--当前项目坐标-->
    <groupId>org.example</groupId>
    <artifactId>mavenProject01</artifactId>
    <version>1.0-SNAPSHOT</version>

    <!--项目的JDK版本及编码-->
    <properties>
        <maven.compiler.source>17</maven.compiler.source>
        <maven.compiler.target>17</maven.compiler.target>
    </properties>

</project>

<project> :pom 文件的根标签,表示当前 maven 项目 ​

<modelVersion>:声明项目描述遵循哪一个 POM 模型版本 ​

  • 虽然模型本身的版本很少改变,但它仍然是必不可少的。目前 POM 模型版本是 4.0.0

坐标 ​

  • <groupId> <artifactId> <version>

  • 定位项目在本地仓库中的位置,由以上三个标签组成一个坐标

<maven.compiler.source> :编译 JDK 的版本 ​

<maven.compiler.target> :运行 JDK 的版本 ​

<project.build.sourceEncoding> : 设置项目的字符集 ​

Maven 坐标 ​

(1)Maven 中的坐标是资源的唯一标识 , 通过该坐标可以唯一定位资源位置 ​

(2)使用坐标来定义项目或引入项目中需要的依赖 ​

Maven 坐标主要组成 ​

(1)groupId:定义当前 Maven 项目隶属组织名称(通常是域名反写,例如:com.itheima) ​

(2)artifactId:定义当前 Maven 项目名称(通常是模块名称,例如 order-service、goods-service) ​

(3)version:定义当前项目版本号 ​

SNAPSHOT: 功能不稳定、尚处于开发中的版本,即快照版本 ​

RELEASE: 功能趋于稳定、当前更新停止,可以用于发行的版本 ​

注意点 ​

(1)上面所说的资源可以是插件、依赖、当前项目 ​

(2) 我们的项目如果被其他的项目依赖时,也是需要坐标来引入的 ​

导入 Maven 项目 ​

(1)方式一 ​

File -> Project Structure -> Modules -> Import Module -> 选择 maven 项目的 pom.xml。 ​

(2)方式二 ​

Maven 面板 -> +(Add Maven Projects) -> 选择 maven 项目的 pom.xml ​

Maven 依赖 ​

依赖配置 ​

依赖:指当前项目运行所需要的 jar 包,一个项目中可以引入多个依赖 ​

配置步骤 ​

(1)在 pom.xml 中编写<dependencies>标签 ​

(2)在<dependencies>标签中使用<dependency>引入坐标 ​

(3)定义坐标的 groupId、artifactId、version ​

(4)刷新依赖:保证每一次引入新的依赖,或者修改现有的依赖配置,都可以加入最新的坐标 ​

举例:需要 spring-context 依赖 ​

xml
<dependencies>
    <!-- 依赖 : spring-context -->
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-context</artifactId>
        <version>6.1.4</version>
    </dependency>
</dependencies>

依赖查找 ​

(1)方法一:利用中央仓库搜索的依赖坐标,以常见的 logback-classic 为例,网址:https://mvnrepository.com/ ​

(2)方法二:IDEA 搜索,快捷键(alt + insert) ​


依赖传递 ​

我们上面在 pom.xml 中配置了一项依赖,就是 spring-context,但是我们通过右侧的 maven 面板可以看到,其实引入进来的依赖,并不是这一项,有非常多的依赖,都引入进来了。我们可以看到如下图所示 ​


为什么会出现这样的现象呢? 那这里呢,就涉及到 maven 中非常重要的一个特性,那就是 Maven 中的依赖传递 ​

所谓 maven 的依赖传递,指的就是如果在 maven 项目中,A 依赖了 B,B 依赖了 C,C 依赖了 D,那么在 A 项目中,也会有 C、D 依赖,因为依赖会传递 ​

那如果,传递下来的依赖,在项目开发中,我们确实不需要,此时,我们可以通过 Maven 中的排除依赖功能,来将这个依赖排除掉 ​

排除依赖 ​

指主动断开依赖的资源,被排除的资源无需指定版本 ​

xml
<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-context</artifactId>
    <version>6.1.4</version>

    <!--排除依赖, 主动断开依赖的资源-->
    <exclusions>
        <exclusion>
            <groupId>io.micrometer</groupId>
            <artifactId>micrometer-observation</artifactId>
        </exclusion>
    </exclusions>
</dependency>

依赖排除案例 ​

(1)默认通过 maven 的依赖传递,传递下来了 micrometer-observation 的依赖 ​


(2)加入排除依赖的配置之后,该依赖就被排除掉了 ​


Maven 生命周期 ​

基本介绍 ​

Maven 的生命周期就是为了对所有的构建过程进行抽象和统一。 描述了一次项目构建,经历哪些阶段 ​

在 Maven 出现之前,项目构建的生命周期就已经存在,软件开发人员每天都在对项目进行清理,编译,测试及部署。虽然大家都在不停地做构建工作,但公司和公司间、项目和项目间,往往使用不同的方式做类似的工作 ​

Maven 从大量项目和构建工具中学习和反思,然后总结了一套高度完美的,易扩展的项目构建生命周期。这个生命周期包含了项目的清理,初始化,编译,测试,打包,集成测试,验证,部署和站点生成等几乎所有构建步骤 ​


每套生命周期包含一些阶段(phase),阶段是有顺序的,后面的阶段依赖于前面的阶段 ​

我们看到这三套生命周期,里面有很多很多的阶段,这么多生命周期阶段,其实我们常用的并不多,主要关注以下几个 ​

clean:移除上一次构建生成的文件 ​

compile:编译项目源代码 ​

test:使用合适的单元测试框架运行测试(junit) ​

package:将编译后的文件打包,如:jar、war 等 ​

install:安装项目到本地仓库 ​

执行 ​

Maven 的生命周期是抽象的,这意味着生命周期本身不做任何实际工作。在 Maven 的设计中,实际任务(如源代码编译)都交由插件来完成 ​

在同一套生命周期中,我们在执行后面的生命周期时,前面的生命周期都会执行 ​


⚠️ 提示:IDEA 的 Maven 控制面板中,提供了快速运行 Maven 命令的功能 ​


命令行操作 ​

操作步骤 ​

(1)打开 Maven 项目对应的磁盘目录 ​

(2)在该目录下打开 cmd 窗口,执行相关命令 ​

相关命令 ​

(1)mvn compile ​

(2)mvn test ​

(3)mvn package ​

(4)mvn install ​


分模块开发与设计 ​

基本介绍 ​

所谓分模块设计,顾名思义指的就是我们在设计一个 Java 项目的时候,将一个 Java 项目拆分成多个模块进行开发 ​

(1)未分模块设计的问题 ​


如果项目不分模块,也就意味着所有的业务代码是不是都写在这一个 Java 项目当中。随着这个项目的业务扩张,项目当中的业务功能可能会越来越多 ​

假如我们开发的是一个大型的电商项目,里面可能就包括了商品模块的功能、搜索模块的功能、购物车模块、订单模块、用户中心等等。这些所有的业务代码我们都在一个 Java 项目当中编写 ​

此时大家可以试想一下,假如我们开发的是一个大型的电商网站,这个项目组至少几十号甚至几百号开发人员,这些开发人员全部操作这一个 Java 项目。此时大家就会发现我们项目管理和维护起来将会非常的困难。而且大家再来看,假如在我们的项目当中,我们自己定义了一些通用的工具类以及通用的组件,而公司还有其他的项目组,其他项目组也想使用我们所封装的这些组件和工具类,其实是非常不方便的。因为 Java 项目当中包含了当前项目的所有业务代码,所以就造成了这里面所封装的一些组件会难以复用 ​

⭐ 总结起来,主要两点问题:不方便项目的维护和管理、项目中的通用组件难以复用 ​

(2)分模块设计 ​

分模块设计我们在进行项目设计阶段,就可以将一个大的项目拆分成若干个模块,每一个模块都是独立的 ​


比如我们可以将商品的相关功能放在商品模块当中,搜索的相关业务功能我都封装在搜索模块当中,还有像购物车模块、订单模块。而为了组件的复用,我们也可以将项目当中的实体类、工具类以及我们定义的通用的组件都单独的抽取到一个模块当中 ​

如果当前这个模块,比如订单模块需要用到这些实体类以及工具类或者这些通用组件,此时直接在订单模块当中引入工具类的坐标就可以了。这样我们就将一个项目拆分成了若干个模块儿,这就是分模块儿设计 ​

分模块儿设计之后,大家再来看。我们在进行项目管理的时候,我就可以几个人一组,几个人来负责订单模块儿,另外几个人来负责购物车模块儿,这样更加便于项目的管理以及项目的后期维护 ​

而且分模块设计之后,如果我们需要用到另外一个模块的功能,我们直接依赖模块就可以了。比如商品模块、搜索模块、购物车订单模块都需要依赖于通用组件当中封装的一些工具类,我只需要引入通用组件的坐标就可以了 ​

⭐ 总结:分模块设计就是将项目按照功能/结构拆分成若干个子模块,方便项目的管理维护、拓展,也方便模块键的相互调用、资源共享 ​

拆分策略 ​

(1)策略一:按照功能模块拆分,比如:公共组件、商品模块、搜索模块、购物车模块、订单模块等 ​

(2)策略二:按层拆分,比如:公共组件、实体类、控制层、业务层、数据访问层 ​

(3)策略三:按照功能模块 + 层拆分 ​


⚠️ 注意事项 ​

分模块开发需要先针对模块功能进行设计,再进行编码,不会先将工程开发完毕,然后进行拆分 ​

Maven 继承 ​

问题引入 ​

在案例项目分模块开发之后啊,我们会看到 tlias-pojo、tlias-utils、tlias-web-management 中都引入了一个依赖 lombok 的依赖。我们在三个模块中分别配置了一次 ​


如果是做一个大型的项目,这三个模块当中重复的依赖可能会很多很多。如果每一个 Maven 模块里面,我们都来单独的配置一次,功能虽然能实现,但是配置是比较繁琐的 ​

基本介绍 ​

我们可以再创建一个父工程 tlias-parent ,然后让上述的三个模块 tlias-pojo、tlias-utils、tlias-web-management 都来继承这个父工程 。 然后再将各个模块中都共有的依赖,都提取到父工程 tlias-parent 中进行配置,只要子工程继承了父工程,依赖它也会继承下来,这样就无需在各个子工程中进行配置了 ​


(1)概念:继承描述的是两个工程间的关系,与 java 中的继承相似,子工程可以继承父工程中的配置信息,常见于依赖关系的继承 ​

(2)作用:简化依赖配置、统一管理依赖 ​

(3)相关配置 ​

xml
<parent>
    <groupId>...</groupId>
    <artifactId>...</artifactId>
    <version>...</version>
    <relativePath>....</relativePath>
</parent>

实现案例 ​

我们当前的项目 tlias-web-management,还稍微有一点特殊,因为是一个 springboot 项目,而所有的 springboot 项目都有一个统一的父工程,就是 spring-boot-starter-parent。 与 java 语言类似,Maven 不支持多继承,一个 maven 项目只能继承一个父工程,如果继承了 spring-boot-starter-parent,就没法继承我们自己定义的父工程 tlias-parent 了 ​

那我们怎么来解决这个问题呢? ​

那此时,大家可以想一下,Java 虽然不支持多继承,但是可以支持多重继承,比如:A 继承 B, B 继承 C。 那在 Maven 中也是支持多重继承的,所以呢,我们就可以让 我们自己创建的三个模块,都继承 tlias-parent,而 tlias-parent 再继承 spring-boot-starter-parent,就可以了。 具体结构如下 ​


Maven 的打包方式 ​

(1)jar(默认):普通模块打包,springboot 项目基本都是 jar 包(内嵌 tomcat 运行) ​

(2)war:普通 web 程序打包,需要部署在外部的 tomcat 服务器中运行 ​

(3)pom:父工程或聚合工程,该模块不写代码,仅进行依赖管理 ​

⚠️ 注意事项 ​

(1)在子工程中,配置了继承关系之后,坐标中的 groupId 是可以省略的,因为会自动继承父工程的 ​

(2) relativePath 指定父工程的 pom 文件的相对位置(如果不指定,将从本地仓库 / 远程仓库查找该工程) ​

.. / 代表的上一级目录 ​

Maven 版本锁定 ​

需求场景 ​

如果项目中各个模块中都公共的这部分依赖,我们可以直接定义在父工程中,从而简化子工程的配置。 然而在项目开发中,还有一部分依赖,并不是各个模块都共有的,可能只是其中的一小部分模块中使用到了这个依赖 ​

比如:在 tlias-web-management、tlias-web-system、tlias-web-report 这三个子工程中,都使用到了 jwt 的依赖。 但是 tlias-pojo、tlias-utils 中并不需要这个依赖,那此时,这个依赖,我们不会直接配置在父工程 tlias-parent 中,而是哪个模块需要,就在哪个模块中配置 ​

而由于是一个项目中的多个模块,那多个模块中,我们要使用的同一个依赖的版本要一致,这样便于项目依赖的统一管理。比如:这个 jwt 依赖,我们都使用的是 0.9.1 这个版本 ​


那假如说,我们项目要升级,要使用到 jwt 最新版本 0.9.2 中的一个新功能,那此时需要将依赖的版本升级到 0.9.2,那此时该怎么做呢 ? ​

第一步:去找当前项目中所有的模块的 pom.xml 配置文件,看哪些模块用到了 jwt 的依赖 ​

第二步:找到这个依赖之后,将其版本 version,更换为 0.9.2 ​

⚠️ 问题:如果项目拆分的模块比较多,每一次更换版本,我们都得找到这个项目中的每一个模块,一个一个的更改。 很容易就会出现,遗漏掉一个模块,忘记更换版本的情况 ​

版本管理实现 ​

在 maven 中,可以在父工程的 pom 文件中通过 <dependencyManagement> 来统一管理依赖版本 ​

(1)父工程 ​

xml
<!--统一管理依赖版本-->
<dependencyManagement>
    <dependencies>
        <!--JWT令牌-->
        <dependency>
            <groupId>io.jsonwebtoken</groupId>
            <artifactId>jjwt</artifactId>
            <version>0.9.1</version>
        </dependency>
    </dependencies>
</dependencyManagement>

(2)子工程 ​

xml
<dependencies>
    <!--JWT令牌-->
    <dependency>
        <groupId>io.jsonwebtoken</groupId>
        <artifactId>jjwt</artifactId>
    </dependency>
</dependencies>

⚠️ 注意事项 ​

(1)在父工程中所配置的 <dependencyManagement> 只能统一管理依赖版本,并不会将这个依赖直接引入进来。 这点和 <dependencies> 是不同的 ​

(2)子工程要使用这个依赖,还是需要引入的,只是此时就无需指定 <version> 版本号了,父工程统一管理。变更依赖版本,只需在父工程中统一变更 ​

面试题:<dependencyManagement> 与 <dependencies> 的区别是什么? ​

(1)<dependencies> 是直接依赖,在父工程配置了依赖,子工程会直接继承下来 ​

(2)<dependencyManagement> 是统一管理依赖版本,不会直接依赖,还需要在子工程中引入所需依赖(无需指定版本) ​

⭐ 属性配置 ​


(1)自定义属性 ​

xml
<properties>
    <lombok.version>1.18.34</lombok.version>
</properties>

(2)引用属性 ​

xml
<dependency>
    <groupId>org.projectlombok</groupId>
    <artifactId>lombok</artifactId>
    <version>${lombok.version}</version>
</dependency>

Maven 聚合 ​

问题引入 ​

分模块设计与开发之后啊,我们的项目被拆分为多个模块,而模块之间的关系,可能错综复杂。 那就比如我们当前的案例项目,结构如下(相对还是比较简单的) ​


此时,tlias-web-management 模块的父工程是 tlias-parent,该模块又依赖了 tlias-pojo、tlias-utils 模块。 那此时,我们要想将 tlias-web-management 模块打包,是比较繁琐的。因为在进行项目打包时,maven 会从本地仓库中来查找 tlias-parent 父工程,以及它所依赖的模块 tlias-pojo、tlias-utils,而本地仓库目前是没有这几个依赖的 ​

所以,我们再打包 tlias-web-management 模块前,需要将 tlias-parent、tlias-pojo、tlias-utils 分别执行 install 生命周期安装到 maven 的本地仓库,然后再针对于 tlias-web-management 模块执行 package 进行打包操作 ​

那此时,大家试想一下,如果开发一个大型项目,拆分的模块很多,模块之间的依赖关系错综复杂,那此时要进行项目的打包、安装操作,是非常繁琐的 ​

通过 maven 的聚合就可以轻松实现项目的一键构建(清理、编译、测试、打包、安装等) ​

聚合实现 ​


(1)聚合:将多个模块组织成一个整体,同时进行项目的构建 ​

(2)聚合工程:一个不具有业务功能的“空”工程(有且仅有一个 pom 文件) ​

一般来说,继承关系中的父工程与聚合关系中的聚合工程是同一个 ​

(3)作用:快速构建项目(无需根据依赖关系手动构建,直接在聚合工程上构建即可) ​

(4)在父工程中添加 modules 标签,实现聚合 ​

实现聚合后,父工程执行某个 maven 命令时,则 tlias-parent 中所聚合的其他模块全部都会执行父工程中所执行的指令,这就是通过聚合实现项目的一键构建(一键清理 clean、一键编译 compile、一键测试 test、一键打包 package、一键安装 install 等) ​

xml
<modules>
    <module>../tlias-pojo</module>
    <module>../tlias-utils</module>
    <module>../tlias-web-management</module>
</modules>

Maven 私服 ​

需求引入 ​

假设现在有两个团队,A 和 B。 A 开发了一个模块 tlias-utils,模块开发完毕之后,将模块打成 jar 包,并安装到了 A 的本地仓库 ​


那此时,该公司的 B 团队开发项目时,要想使用 tlias-utils 中提供的工具类,该怎么办呢? 对于 maven 项目来说,是不是在 pom.xml 文件中引入 tlias-utils 的坐标就可以了呢? ​


大家可以思考一下,当 B 团队在 maven 项目的 pom.xml 配置文件中引入了依赖的坐标之后,maven 是如何查找这个依赖的? 查找顺序为: ​

(1)本地仓库:本地仓库中是没有这个依赖 jar 包的。 ​

(2)远程中央仓库:由于该模块时自己公司开发的,远程仓库中也没有这个依赖 ​

因为目前 tlias-utils 这个依赖,还在 A 的本地仓库中的。 B 电脑上的 maven 项目,是不可能找得到 A 电脑上 maven 本地仓库的 jar 包的。 那此时,大家可能会有一个想法:因为 A 和 B 都会连接中央仓库,我们可以将 A 本地仓库的 jar 包,直接上传到中央仓库,然后 B 从中央仓库中下载 tlias-utils 这个依赖 ​


这个想法很美好,但是现实很残酷。这个方案是行不通的,因为中央仓库全球只有一个,不是什么人都可以往中央仓库中来上传 jar 包的,我们是没有权限操作的 ​

那此时,maven 的私服就出场了,私服其实就是架设在公司局域网内部的一台服务器,就是一种特殊的远程仓库 ​

有了私服之后,各个团队就可以直接来连接私服了。 A 连接上私服之后,他就可以把 jar 包直接上传到私服当中。我公司自己内部搭建的服务器,我是不是有权限操作呀,把 jar 包上传到私服之后,我让 B 团队的所有开发人员也连接同一台私服。连接上这一台私服之后,他就会根据坐标的信息,直接从私服当中将对应的 jar 包下载到自己的本地仓库,这样就可以使用到依赖当中所提供的一些工具类了。这样我们就可以通过私服来完成资源的共享 ​


而如果我们在项目中需要使用其他第三方提供的依赖,如果本地仓库没有,也会自动连接私服下载,如果私服没有,私服此时会自动连接中央仓库,去中央仓库中下载依赖,然后将下载的依赖存储在私服仓库及本地仓库中 ​

基本介绍 ​

(1)私服 ​

是一种特殊的远程仓库,它是架设在局域网内的仓库服务,用来代理位于外部的中央仓库,用于解决团队内部的资源共享与资源同步问题 ​

(2)依赖查找顺序 ​

本地仓库 ​

私服仓库 ​

中央仓库 ​

(3) ⚠️ 注意事项 ​

私服在企业项目开发中,一个项目/公司,只需要一台即可(无需我们自己搭建,会使用即可) ​

资源上传与下载 ​


第一步配置:在 maven 的配置文件中配置访问私服的用户名、密码 ​

第二步配置:在 maven 的配置文件中配置连接私服的地址(url 地址) ​

第三步配置:在项目的 pom.xml 文件中配置上传资源的位置(url 地址) ​

配置好了上述三步之后,要上传资源到私服仓库,就执行执行 maven 生命周期:deploy ​

私服仓库说明 ​

RELEASE:存储自己开发的 RELEASE 发布版本的资源 ​

SNAPSHOT:存储自己开发的 SNAPSHOT 发布版本的资源 ​

Central:存储的是从中央仓库下载下来的依赖 ​

项目版本说明 ​

RELEASE(发布版本):功能趋于稳定、当前更新停止,可以用于发行的版本,存储在私服中的 RELEASE 仓库中 ​

SNAPSHOT(快照版本):功能不稳定、尚处于开发中的版本,即快照版本,存储在私服的 SNAPSHOT 仓库中 ​

相关配置 ​

⚠️ 注意事项:以下内容只是案例,相关信息需要根据实际修改

以下配置完成之后,我们就可以在 tlias-parent 的 maven 面板中执行 deploy 生命周期,将项目发布到私服仓库中 ​

(1)设置私服的访问用户名/密码(在自己 maven 安装目录下的 conf / settings.xml 中的 servers 中配置 ​

xml
<server>
    <id>maven-releases</id>
    <username>admin</username>
    <password>admin</password>
</server>

<server>
    <id>maven-snapshots</id>
    <username>admin</username>
    <password>admin</password>
</server>

(2)设置私服依赖下载的仓库组地址(在自己 maven 安装目录下的 conf/settings.xml 中的 mirrors 中配置) ​

xml
<mirror>
    <id>maven-public</id>
    <mirrorOf>*</mirrorOf>
    <url>http://localhost:8081/repository/maven-public/</url>
</mirror>

(3)设置私服依赖下载的仓库组地址(在自己 maven 安装目录下的 conf/settings.xml 中的 profiles 中配置) ​

xml
<profile>
    <id>allow-snapshots</id>
    <activation>
        <activeByDefault>true</activeByDefault>
    </activation>
    <repositories>
        <repository>
            <id>maven-public</id>
            <url>http://localhost:8081/repository/maven-public/</url>
            <releases>
                <enabled>true</enabled>
            </releases>
            <snapshots>
                <enabled>true</enabled>
            </snapshots>
        </repository>
    </repositories>
</profile>

(4)IDEA 的 maven 工程的 pom 文件中配置上传(发布)地址(直接在 tlias-parent 中配置发布地址) ​

xml
<distributionManagement>
    <!-- release版本的发布地址 -->
    <repository>
        <id>maven-releases</id>
        <url>http://localhost:8081/repository/maven-releases/</url>
    </repository>
    <!-- snapshot版本的发布地址 -->
    <snapshotRepository>
        <id>maven-snapshots</id>
        <url>http://localhost:8081/repository/maven-snapshots/</url>
    </snapshotRepository>
</distributionManagement>

分模块搭建项目 ​

⚠️ 层级不显示问题 ​


⚠️ 解决已忽略的 pom ​


创建方法 ​

(1)创建 springboot 项目,删除不必要的文件夹,只留下 pom 文件 ​

⚠️ 注意:这里只做依赖的管理,不写代码,需要删除 build 标签 ​

(2)非 controller 层,创建 maven 模块 ​

(3)controller 层,创建 springboot 项目模块 ​

controller 层中 pom 文件的 bulid 标签如下 ​

xml
<build>
    <plugins>
        <plugin>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-maven-plugin</artifactId>
        </plugin>
    </plugins>
</build>

(4)在父工程中声明子模块,同时指定打包方式 ​

pom:父工程或聚合工程,该模块不写代码,仅进行依赖管理 ​

jar(默认):普通模块打包,springboot 项目基本都是 jar 包(内嵌 tomcat 运行) ​

xml
<!-- 父模块需要继承 springboot 依赖-->
<parent>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-parent</artifactId>
    <version>3.4.11</version>
    <relativePath/> <!-- lookup parent from repository -->
</parent>

<!-- 声明需要聚合的子模块 -->
<modules>
    <module>accompany-common</module>
    <module>accompany-pojo</module>
    <module>accompany-service</module>
</modules>

<!-- 父模块的声明 -->
<groupId>com.accompany</groupId>
<artifactId>accompany-system</artifactId>
<version>0.0.1-SNAPSHOT</version>

<!--父模块的打包方式为 pom(只做依赖管理,不写代码,默认为 jar)-->
<packaging>pom</packaging>

在每个子模块中添加对父模块的依赖 ​

xml
<!--声明父模块的依赖-->
<parent>
    <artifactId>accompany-system</artifactId>
    <groupId>com.accompany</groupId>
    <version>0.0.1-SNAPSHOT</version>
</parent>

<!--
    子模块的声明,用 <artifactId> 标签声明 maven 坐标即可,
    无需指定 groupId(继承了父类,无需重复声明)
-->
<artifactId>accompany-service</artifactId>
<version>0.0.1-SNAPSHOT</version>

依赖管理 ​

(1)在父模块中声明项目需要的所有依赖并同一管理版本 ​

(2)子模块需要使用某个依赖时,需要使用 <dependency> 标签声明父类中引入的依赖,且无需指定版本号(父类中统一管理) ​

(3)对于子模块中需要使用的特定依赖,可以直接引入,并指定版本号,无需交给父类管理 ​

xml
<!--依赖版本管理-->
<properties>
    <springboot-starter>3.4.11</springboot-starter>
</properties>

<!--
    1. 依赖管理
    2. 注意点
        (1)这里只是依赖管理,子模块需要使用某个依赖时需要使用 <dependency> 标签声明,
            且无需指定版本(父模块中统一管理)
        (2)若子模块需要用到特定的依赖,可以直接指定版本,可以不用父类管理
-->
<dependencyManagement>
    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter</artifactId>
            <version>${springboot-starter}</version>
        </dependency>
    </dependencies>
</dependencyManagement>

(4)controller 层 所在的模块,可以依赖一下其他子模块,然后再声明本模块需要的依赖 ​

xml
<!--声明对其他子模块的依赖-->
<dependency>
    <groupId>com.accompany</groupId>
    <artifactId>accompany-common</artifactId>
    <version>0.0.1-SNAPSHOT</version>
</dependency>

<dependency>
    <groupId>com.accompany</groupId>
    <artifactId>accompany-pojo</artifactId>
    <version>0.0.1-SNAPSHOT</version>
</dependency>

<!--本模块所需要的依赖-->
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-web</artifactId>
</dependency>

......