MAVEN
1. 开发中遇到的那些事
-
大家都是一样的代码,怎么别人机器上可以运行,我的机器不能正常运行?
-
项目组新来了个MM,我想主动帮他把项目环境搭好把项目帮她运行起来,但问题是我也记得不全了?
-
上一个项目用到很多jar,这个项目我要用其中的一部分怎么办?拷贝过来?拷贝哪些?版本升级怎么办?
-
自己写了个很牛X的工具类,分享到其它项目组,那后续更新跟维护怎么办?从此你要花很多精力在这些小事上……
总是就是项目的环境,依赖的jar很多时候会很混乱,浪费我们过多的精力跟时间。于是MAVEN要上场了……
2. 什么是MAVEN
-
MAVEN是基于POM(工程对象模型),通过一小段描述来对项目的代码、文件进行管理的工具。简单的说就是管理我们项目中依赖的包之间的关系。
-
MAVEN是一个跨平台的项目管理工具,它是使用java开发的,依赖于JDK1.6及以上。
-
Maven主要2大功能:管理依赖(jar包管理)、项目构建。
2.1 项目构建
2.2 项目构建方式
Eclipse、Maven、Ant、Gradle……
3. MAVEN的使用
3.1 maven的下载
https://maven.apache.org/
3.2 配置环境变量
3.3 测试
cmd小窗口输入命令mvn -v,如果出现如下截图则表示安装成功
3.4 配置本地仓库
-
打开%MAVEN_HOME%/bin目录下的settings.xml文件,设置localRepository值,如:
< localRepository >本地仓库路径</ localRepository>
-
这里设置的路径是我们本地仓库的位置,管理的所有的jar包的目录。不配置默认的本地仓库路径为 ${user.home}/.m2/repository 。由于时间久了这个目录很占空间,这个默认路径在C盘,所以建议配置在非C盘路径下。
3.5 配置中央仓库
- 打开%MAVEN_HOME%/bin目录下的settings.xml文件,在mirrors下设置如下内容:
<mirror>
<id>alimaven</id>
<mirrorOf>central</mirrorOf>
<name>aliyun maven</name>
<url>http://maven.aliyun.com/nexus/content/repositories/central/</url>
</mirror>
<!-- 中央仓库1 -->
<mirror>
<id>repo1</id>
<mirrorOf>central</mirrorOf>
<name>Human Readable Name for this Mirror.</name>
<url>http://repo1.maven.org/maven2/</url>
</mirror>
<!-- 中央仓库2 -->
<mirror>
<id>repo2</id>
<mirrorOf>central</mirrorOf>
<name>Human Readable Name for this Mirror.</name>
<url>http://repo2.maven.org/maven2/</url>
</mirror>
- 把远程中央仓库设置成阿里云的可以提高我们下载jar的速度,因为是在国内,而默认的中央仓库在国外很慢。
- 镜像可以配置多个,按照顺序自上而下寻找。
3.6 配置JDK版本
- 打开%MAVEN_HOME%/bin目录下的settings.xml文件,在profiles标签下设置如下内容:
<profile>
<id>JDK-1.8</id>
<activation>
<activeByDefault>true</activeByDefault>
<jdk>1.8</jdk>
</activation>
<properties>
<maven.compiler.source>1.8</maven.compiler.source>
<maven.compiler.target>1.8</maven.compiler.target>
<maven.compiler.compilerVersion>1.8</maven.compiler.compilerVersion>
</properties>
</profile>
3.7 配置说明
Maven是在settings.xml文件中进行配置。
全局配置和局部配置
settings.xml文件一般存在于两个位置:
- 全局配置: ${MAVEN_HOME}/conf/settings.xml
- 用户配置: 用户目录/.m2/settings.xml
需要注意的是:局部配置优先于全局配置。
配置优先级从高到低:pom.xml> user settings > global settings
如果这些文件同时存在,会合并配置内容,如果有重复的配置,优先级高的配置会覆盖优先级低的。
3.8 项目构建
-
创建一个目录用来放我们想创建的项目,CMD进入此目录,然后执行
mvn archetype:generate -DgroupId=com.blb.seven -DartifactId=FirstMvnPro -Dversion=1.0 -DarchetypeArtifactId=maven-archetype-quickstart -DinteractiveMode=false
其中com.blb.seven为设置的包名,FirstMvnPro 为设置的项目名。
3.9 MAVEN命令的使用
3.9.1 mvn compile
对项目进行编译,代码生成的文件都在target目录。
3.9.2 mvn package
对项目进行打包。java项目打成jar包,web项目打成war包,在pom文件中可以配置。
3.9.3 mvn install
-
对项目进行安装,把打包好的内容安装到本地仓库。
-
如果没有执行compile test package命令直接执行install命令则会默认先把compile、test、package执行一遍先。
3.9.4 mvn clean
- 把生成的内容全部删除。
3.10 IDEA使用Maven
3.10.1 在IDEA配置Maven
下面我们将在IDEA中配置Maven,这样我们就能在IDEA中创建Maven项目了
点击File菜单 -> Settings -> Build Tools 找到Maven
主要配置:
- Maven home directory 可以配置Maven所在的目录
- User settings file 是配置文件的路径
- Local repository 是本地仓库的路径
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-FksV9eNk-1618921498453)(assets/5-idea.png)]
3.10.2 在IDEA创建Maven项目
点击File -> New -> Project
选择Maven,然后勾选Create from archetype
(这个archetype是选择固定的架构模板来创建项目),选择maven-archetype-webapp
(web开发常用的架构)
点击Next,这里输入Name、Location、GroupId、ArtifactId和Version,可以理解为项目名称、位置、开发组名、项目名、版本号
点击Next,这里也是配置Maven的目录和配置文件、本地仓库的路径
点击Finish,就完成了一个Maven项目的创建
4.MAVEN核心概念
4.1 坐标
maven仓库中存放跟管理了大量的项目构建,在maven中坐标是为了定位一个唯一确定的包。我们在仓库中要找到我们需要的目标,只要知道目标的坐标即可。
4.2 坐标的组成
groupId: 定义当前的Maven组织名称
artifactId: 定义实际项目名称
version: 定义当前项目版本号
简称GAV坐标,在pom.xml文件中的配置如下:
<groupId>com.blb.seven</groupId><!-- 组织名 -->
<artifactId>Hello</artifactId><!-- 项目名 -->
<version>0.0.1-SNAPSHOT</version><!-- 版本号 -->
4.3 管理依赖
在maven项目中,最重要的文件是pom.xml文件,所有的配置都在此文件中,包括最重要的依赖管理。每一个依赖都在dependencies标签下,通过GAV坐标引入我们需要的依赖。例子如下:
<dependency>
<groupId>junit</groupId> <!-- 组织名 -->
<artifactId>junit</artifactId><!-- 项目名 -->
<version>4.11</version><!-- 版本号 -->
<scope>test</scope><!-- 范围 -->
</dependency>
在这个例子中除了GAV坐标以外,还有一个scope表示依赖的范围。
4.4 范围
依赖范围(scope) | 对主代码有效 | 对测试代码有效 | 打包运行时有效 | 例子 |
---|---|---|---|---|
compile | Y | Y | Y | log4j |
test | - | Y | - | junit |
provided | Y | Y | - | servlet-api |
runtime | - | - | Y | jdbc Driver |
system | Y | Y | - |
**tip: **
-
如果没有设置这个属性则默认为compile
-
当范围为system时需要跟systemPath搭配使用,表示依赖本地jar包。如:
<dependency>
<groupId>com.hellojar</groupId>
<artifactId>IncludeJarPro</artifactId>
<version>1.0</version>
<scope>system</scope>
<!-- 表示要依赖本地此路径下的此jar包 -->
<systemPath>F:\IncludeJarPro-1.0.jar</systemPath>
</dependency>
4.5 依赖传递
在maven中,依赖是可以传递的,假设存在三个项目,分别是项目A,项目B以及项目C。假设C依赖B,B依赖A,那么我们可以根据maven项目依赖的特征不难推出项目C也依赖A。
tip:
依赖不能形成闭环,比如A->B, B->C, C->A
4.6 依赖冲突
- 在同一个pom文件中,如果存在2个冲突的依赖的话,采取的后面覆盖前面的原则。如:
<!-- 同时定义了4.7版本的junit跟4.8版本的junit,后面覆盖前面的。最终使用的版本是4.8 -->
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.7</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.8</version>
<scope>test</scope>
</dependency>
-
在不同的pom文件中,如果存在2个冲突的依赖的话,先采用路径最短原则,路径相同再采用最先声明优先原则。
比如:A->B->C->X(1.0), A->D->X(2.0),1.0版本的X跟2.0版本的X都会传递到A,那么A究竟会使用哪个版本呢?前面A到X(1.0)路径是3,后面A到X(2.0)路径是2,所以采用路径最短原则,使用X(2.0)。
那么当路径相同时, A->B->Y(1.0), A->C->Y(2.0),Y(1.0)跟Y(2.0)到A的路径都是2,那么采用谁声明靠前就使用哪个版本的Y。
4.7 依赖排除
当我们项目A依赖B,B依赖10个jar,则A间接依赖这10个jar,此时当我们依赖B的时候可以定义这10个jar中的哪些排除在外,不要依赖。这就叫做排除依赖。
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-beans</artifactId>
<version>5.2.4.RELEASE</version>
<!-- 将依赖传递过来的spring-jcl排除在外 -->
<exclusions>
<exclusion>
<groupId>org.springframework</groupId>
<artifactId>spring-jcl</artifactId>
</exclusion>
</exclusions>
</dependency>
4.8 可选依赖
当我们项目A依赖B,B依赖10个jar,则A间接依赖这10个jar,此时当项目B被依赖的时候可以定义哪些不给项目A依赖。这叫做可选依赖。
可选依赖跟依赖排除的区别是:可选依赖是我不给,依赖排除是我不要。
项目B内容如下:
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.8</version>
<!-- 这个选项默认是false,设置true以后表示这个依赖不传递给其他依赖 -->
<optional>true</optional>
</dependency>
4.9 版本锁定
采用直接锁定版本的方法确定依赖jar包的版本,版本锁定后则不考虑依赖的声明顺序或依赖的路径,以锁定的版本为准添加到工程中,此方法在企业开发中经常使用。
版本锁定的使用方式:
第一步:在dependencyManagement标签中锁定依赖的版本
第二步:在dependencies标签中声明需要导入的maven坐标
①在dependencyManagement标签中锁定依赖的版本
②在dependencies标签中声明需要导入的maven坐标
4.10 继承和聚合
POM项目对象模型把项目以面向对象的方式管理,项目之间可以有继承、聚合这些特性。
继承,项目之间可以继承,子项目可以继承父项目的依赖和插件
子项目的pom.xml中用parent继承父项目,父项目的打包方式必须是pom
<parent>
<artifactId>父项目artifactId</artifactId>
<groupId>父项目groupId</groupId>
<version>父项目version</version>
</parent>
聚合,一个项目可以把多个项目整合到一起打成一个包,部署到一起,聚合项目用modules配置被聚合的项目
<modules>
<module>项目1</module>
<module>项目2</module>
</modules>
继承和聚合一般一起使用,我们可以在一个大项目中创建多个子项目以完成不同的业务,子项目继承父项目,父项目聚合所有子项目。
4.11 Maven的仓库
我们下载的jar包保存在哪里呢?
Maven的仓库是保存依赖jar包文件的地方。
Maven仓库的分类
Maven仓库分为:
-
本地仓库
在本机保存jar包的目录 -
远程仓库
自己搭建的服务器,用于保存jar包文件,以提高jar下载速度和安全性 -
中央仓库
由maven团队维护的服务器,保存大量jar包地址:https://repo1.maven.org 、 https://repo2.maven.org
这三种仓库工作的流程是:
当项目需要某个jar包时,先从本地仓库查找,如果有就返回,如果没有就到远程仓库查询,如果找到就返回jar包并保存到本地仓库,如果还没找到就到中央仓库查找,如果找到了就保存到远程仓库和本地仓库中,如果没有就查找失败了。