Edhug

导航

Maven项目管理

项目为什么选用Maven进行构建

Maven主要服务于基于java平台的项目构建,依赖管理和项目信息管理。Maven项目对象模型(POM),可以通过一小段描述信息
来管理项目的构建。
添加第三方jar包:最原始的做法,我们是手动复制ar包到项目WEB-INF/ib下,每个项目都会有一份,造成大量重复文件。而Maven将jar包放在本地仓库中统一管理,需要jar包只需要用坐标的方式引用即可。如下图:

<dependency>
<groupId>org.apache.httpcomponents</groupId>
<artifactId>httpclient</artifactId>
<version>4.5.8</version>
</dependency>

jar包之间的依赖关系:jar包之间往往不是独立的,很多jar需要在其他jar包的支持下才能够正常工作,称为jar包之间的依赖关系。如果我们手动去导入,要知道jar包之间的依赖关系并全部导入是及其麻烦而且容易出错的。如果使用Maven,它能够将当前jar包所依赖的其他所有jar包全部导入。

获取第三方jar包:开发过程中我们需要用到很多jar包,每个jar包在官网获取的方式不尽相同,给工作带来了额外困难。但是使用Maven可以以坐标的方式依赖一个jar包,Maven从中央仓库进行下载,并同时下载这个jar包依赖的其他jar包。

、Maven仓库分几种?

Maven仓库分为两大类:
1、远程仓库。在远程仓库中又分成了3种:。
2、本地仓库:默认C:Users)用户名1.m2目录可通过配置maven安装目录下/conf/settings.xml中的localRepository属性修改

  • 中央仓库(所有的jar包的来源但是慢国外网站):http://repo.maven.apache.org/maven2
  • 私服:自己搭建的地址
  • 其它公共库:如阿里云:http://maven.aliyun.com/nexus/content/groups/public
    Maven会先搜索本地仓库(repository),发现本地没有然后从远程仓库(中央仓库)获取。
    中央仓库是一个国外仓库,网络速度不太友好,最好从其镜象处下载。国内可以用阿里云下的服务器。【其它公共库】
    ·也有通过Nexus搭建的私服进行获取的。[私服】
    Maven中的仓库分为两种,SNAPSHOT快照仓库和RELEASE发布仓库。
    SNAPSHOT快照仓库用于保存开发过程中的不稳定版本,RELEASE正式仓库则是用来保存稳定的发行版本。
    定义一个组件/模块为快照版本,只需要在pom文件中在该模块的版本号后加上-SNAPSHOT 即可(注意这里必须是大写),如下:
    com.czbk.
    kyjgs.interview
    0.1-SNAPsHoT
    jar

私服的作用

私服是一种特殊的远程仓库,它是架设在局域网内的仓库服务,私服代理广域网上的远程仓库,供局域网内的Maven用户使用。
当Maven需要下载资源的时候,它从私服请求,如果私服上不存在该资源,则从外部的远程仓库下载,先缓存在私服上之后,再为Maven的下载请求提供服务。我们还可以把一些无法从外部仓库下载到的资源上传到私服上。
Maven私服的5个特性:
1、节省自己的外网带宽:减少重复请求造成的外网带宽消耗。
2、加速Maven构建:如果项目配置了很多外部远程仓库的时候,构建速度就会大大降低。
3、部署第三方jar包:有些jar无法从外部仓库获得或者未开源,不允许放到公网上。把这些构件部署到内部仓库(私服)中,供内部Maven项目使用。
4、提高稳定性,增强控制:Intemnet不稳定的时候,Maven构建也会变的不稳定,一些私服软件还提供了其他的功能。
5、降低中央仓库的负荷:Maven中央仓库被请求的数量是巨大的,配置私服也可以大大降低中央仓库的压力。

Maven生命周期

Maven的生命周期是一个抽象的概念,并不具体指某个操作,是Maven经过长时间思考和分析后总结出来的。它包括了一个项目
的清理、初始化、编译、测试、打包、集成测试、验证、部署和站点生成等一系列的构建流程。
Maven有三套相互独立的生命周期,分别是Clean、Default和Site。每个生命周期包含一些阶段,阶段是有顺序的,后面的阶段
依赖于前面的阶段。
1、Clean生命周期:清理项目,包含三个阶段:
pre-clean:执行清理前需要完成的工作。
clean:清理上一次构建生成的文件。
post-clean:执行清理后需要完成的工作
2、Default生命周期:构建项目,重要的阶段如下:
validate:验证工程是否正确,所有需要的资源是否可用。
compile:编译项目的源代码。
test:使用合适的单元测试框架来测试已编译的源代码。这些测试不需要已打包和布署。
package:把已编译的代码打包成可发布的格式,比如jar、war等。
integration-test:如有需要,将包处理和发布到一个能够进行集成测试的环境。
verify:运行所有检查,验证包是否有效且达到质量标准。
install:把包安装到maven本地仓库,可以被其他工程作为依赖来使用。
deploy:在集成或者发布环境下执行,将最终版本的包拷贝到远程的repository,使得其他的开发者或者工程可以共享。
3、Site生命周期:目的是建立和发布项目站点,方便团队交流和发布项目信息。阶段如下:
-pre-site:生成项目站点之前需要完成的工作
-site:生成项目站点文档:
-post-site:生成项目站点之后需要完成的工作
-site-deploy:将项目站点发布到服务器

各个生命周期相互独立,一个生命周期的阶段前后依赖。
·mvn clean:调用Clean生命周期的clean阶段,实际执行pre-clean和clean阶段
mvntest:调用Default生命周期的test阶段,实际执行test以及之前所有阶段install以及之前所有阶段。
mvn clean install :调用 Clean生命周期的 clean 阶段和 Default 生命周期的install阶段,实际执行pre-clean和clean,
而我们在IDEAMaven中,也可以看到Maven生命周期的操作:
6ea559bd-16fb-4813-b868-644c93f6c364

Maven坐标的意义

<dependency>
  <groupId>junit</groupId>
  <artifactId>junit</artifactId>
  <version>3.8.2</version>
</dependency>

在Maven中使用坐标表示资源的唯一标识,Maven的坐标元素包括groupld、artifactldversion、packaging。
只要提供正确的坐标元素,Maven就能找到对应的资源。它首先去你的本地仓库查找,没有的话去远程仓库下载。
groupld:组织ID,定义当前Maven项目隶属组织或公司名称(通常是域名反写,例如:com.czbk.kyjgs)
Maven项目和实际项目不一定是一对一的关系。如Spring FrameWork项目,其对应的Maven项目会有很多,如spring-core、spring-context等。
这是由于Maven中模块的概念,因此一个实际项目往往会被划分成很多模块。
artifactld:该元素定义当前实际项目中的一个Maven项目(模块)。
推荐的做法是使用实际项目名称作为artifactld的前缀。比如上例中的junit,junit就是实际的项目名称,方便而且直观。
在默认情况下,Maven生成的资源,会以artifactld作为文件头。例如junit-3.8.1.jar,使用实际项目名称作为前缀,就能方便的从本地仓库找到某个项目的资源。
version:该元素定义了使用资源的版本。
如上例中junit的版本是4.13-BETA,也可以改为4.1.2表示使用4.1.2版本的junit。
packaging:定义Maven项目打包的方式。打包方式通常与所生成资源的文件扩展名对应。
如上例中没有packaging,则默认为jar包,最终的文件名为junit-4.13-BETA.jar。当然也可以打包成war等。

Maven的传递依赖

maven依赖主要有两大原则:
1、路径最近者优先会被解析使用。
相同jar不同版本,根据依赖的路径长短来决定引入哪个依赖。该例中X(1.0)的路径长度为3,而X(2.0)的路径长度为2,因此X(2.0)

依赖链路二:F->D->X(2.0)```
**2、第一声明者优先**
依赖调解第一原则不能解决所有问题,比如这样的依赖关系:
```A -> B -> Y(1.0)
C-> D -> Y(2.0)```
Y(1.0)和Y(2.0)的依赖路径长度是一样的,都为2。Maven定义了依赖调解的第二原则。
在依赖路径长度相等的前提下,在POM中依赖声明的顺序决定了谁会被解析使用,顺序最前的那个依赖优胜。该例中,如果A
的依赖声明在C之前,那么Y(1.0)就会被解析使用。
###Maven处理依赖冲突的方式
依赖冲突是指项目依赖的jar包有多个版本,因而造成了包版本冲突。
java中常见包冲突异常为:NoClassDefFoundError、 ClassNotFoundException, NoSuchMethodError.
制造依赖冲突,maven的pom文件中加入以下依赖:
org.apache.poi poi-ooxml 3.10.1 com.alibaba easyexcel 2.2.8 ``` ``` 代码中创建一个类,执行以下代码: public static void main(string[] args) { //1.获取文件地址 String fileName = "/excel/test.xlsx"; //2、调用easyExce1里面的方法实现写操作 EasyExcel.write(fileName, Object.class).sheet("某报表").dowrite(new ArrayList<>(); ``` ![2a77b01a-3a58-49d6-b8b3-b8bbb5d2cd67](https://img2024.cnblogs.com/blog/3482053/202610/3482053-20261014150040675-106527594.png) 因为我当前的easyexcel入的poi是3.17版本的,但是因为根据maven依赖原则,实际引入的poi版本确实是3.10.1版本的。 而DefaultTempFileCreationStrategy这个类在3.10.1这个版本并没有,只有3.17版本才有,所以报了这个错误 解决jar包冲突 分析知问题的主要原因是需要使用poi的3.17版本。那么解决方式就是让我们的项目引入此版本 ``` 1、方法一:pom文件中增加内容,强制使用3.17版本 org.apache.poi poi 3.17 ``` 2、通过插件分析pom文件,解决冲突。 dea安装Maven Helper插件,pom文件中看到dependency analyzer标志,说明maven helper插件就安装成功了,如下图: ![d31d0256-c6fe-4c8b-bb42-91b5e5104c04](https://img2024.cnblogs.com/blog/3482053/202610/3482053-20261014161702159-1788790886.png) 点击dependency analyzer之后就会进入到下面的页面 ![图片](https://img2024.cnblogs.com/blog/3482053/202610/3482053-20261014161813441-608734276.png)

Maven常见的依赖范围

maven中,通过标签可以指定jar包得依赖范围,如下图:

junit
junit
4.12

compile

关于scope的常用具体值如下:
compile:默认的scope,运行期有效,会打入包中。
provided:编译期有效,运行期不需要提供,不会打入包中。可减少自己的jar包对别人项目的jar包冲突。
runtime:编译不需要,在运行期有效,会入包中。(接口与实现分离)
test:测试需要,不会打入包中,src包中不能使用。
根据scope值的不同,对于依赖的jar包使用范围不同,如下图:
f7c56f93-d206-45ad-802e-c60782239ba1

posted on 2026-10-16 08:48  饿得慌~  阅读(5)  评论(0)    收藏  举报