前言
使用Maven后每个jar包只在本地仓库中保存一份,需要jar包的工程只需要维护一个文本形式的jar包的引用。只需要在项目中以坐标的方式依赖一个jar包,Maven会自动从中央仓库进行下载,并同时自动下载jar包所依赖的其他jar包
。对于Jar包之间的冲突处理
,Maven中内置了两条依赖原则:最短路径者优先和先声明者优先
在实际生产环境中,利用maven将项目拆分成多个工程模块
项目规模增加到一定程度后,可能每个模块都需要运行在独立的服务器上,maven可实现项目的分布式部署
互联网上根据groupId、artifactId查找maven依赖
如:查找oracle驱动包
一.Maven——自动化构建工具
1.1 安装部署
查看jdk版本:
解压安装包:
链接:网盘地址
提取码:1256
设置环境变量并查看配置路径以及maven版本:
在系统变量里面创建M2_HOME变量,并赋值
变量:M2_HOME
值:maven安装目录
在Path变量中,添加maven环境变量
变量:Path
值:%M2_HOME%\bin
path
mvn -v
1.2 Maven的本地仓库的配置
(1)更改本地仓库地址,默认在C:\Users\Administrator.m2\repository
<localRepository>E:\JetBrains\repository</localRepository>
(2)配置阿里云镜像(下载速度快)
<mirror>
<id>nexus-aliyun</id>
<mirrorOf>central</mirrorOf>
<name>Nexus aliyun</name>
<url>http://maven.aliyun.com/nexus/content/groups/public</url>
</mirror>
(3)配置全局jdk
<profile>
<id>jdk18</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>
1.3 idea配置Maven
在idea的setting中配置
Maven home directory:指定本地 Maven 的安装目录所在
User settings file / Local repository:指定 Maven 的 settings.xml 位置和本地仓库位置。
Import Maven projects automatically:表示 IntelliJ IDEA 会实时监控项目的 pom.xml 文件,进行项目变动。勾选上
Automatically download:在 Maven 导入依赖包的时候是否自动下载源码和文档。默认是没有勾选的。不建议勾选
VM options for importer:可以设置导入时的VM参数。一般这个都不需要主动改,除非项目真的导入太慢了我们再增大此参数
1.4 构建环节
(1)清理:删除以前的编译结果,为重新编译做好准备
(2)编译:将Java源程序编译为字节码文件
(3)测试:针对项目中的关键点进行测试,确保项目在迭代开发过程中关键点的正确性
(4)报告:在每一次测试后以标准的格式记录和展示测试结果
(5)打包:将一个包含诸多文件的工程封装为一个压缩文件用于安装或部署。Java工程对应jar包,Web工程对应war包
(6)安装:在Maven环境下特指将打包的结果——jar包或war包安装到本地仓库中
(7)部署:将打包的结果部署到远程仓库或将war包部署到服务器上运行
二.Maven核心概念
2.1 POM
项目对象模型,将Java工程的相关信息封装为对象
2.2 坐标
使用如下三个向量在Maven的仓库中唯一的确定一个唯一的jar。
(1)groupId:公司或组织的域名倒序+当前项目名称
(2)artifactId:当前项目的模块名称
(3)version:当前模块的版本
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.0</version>
<scope>test</scope>
</dependency>
2.3 如何通过坐标到仓库中查找jar包
(1)将gav三个向量连起来
groupId + artifactId+ version
(2)以连起来的字符串作为目录结构到仓库中查找
注:
自己的Maven工程必须执行安装操作才会进入仓库
命令:
mvn install
三.依赖的范围和传递性
3.1 范围的含义
编译时,maven 会将与编译相关的依赖引入classpath中,测试时,maven会将与测试相关的的依赖引入到classpath中,运行时,maven会将与运行相关的依赖引入classpath中,依赖范围就是用来控制依赖于这三种classpath的关系
3.2 范围的分类
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
<scope>test</scope>
</dependency>
scope标签就是依赖范围的配置,默认是compile,可选配置有test、provided、runtime、system、import
1) compile,默认依赖范围
对于编译、测试、运行三种classpath都有效
,即main目录下的java代码可以访问这个范围的依赖,test目录下的java代码可以访问这个范围的依赖,部署到tomcat服务器上运行时会放在WEB-INF的lib目录下
2) test,针对测试
main目录下的java代码不可以访问这个范围的依赖,test目录下的java代码可以访问这个范围的依赖,部署到tomcat服务器上运行时不会放在WEB-INF的lib目录下
3) provided只对编译和测试有效,对运行无效
main目录下的java代码可以访问这个范围的依赖,test目录下的java代码可以访问这个范围的依赖,部署到tomcat服务器上运行时不会放在WEB-INF的lib目录下
典型范例:servlet-api在服务器运行时,servlet容器会提供相应的jar,无需再次引入
4) runtime只对测试和运行有效,对编译无效
典型范例:JDBC的驱动实现,项目主代码编译的时候只需要JDK提供的JDBC接口,只有在测试和运行的时候才需要实现上述接口的具体JDBC驱动
5) system
与classpath的关系与 provided依赖范围完全一致,但是系统依赖范围必须通过配置systemPath元素来显示指定依赖文件的路径,此类依赖不是由maven仓库解析的,而且往往与本机系统绑定,可能造成构件的不可移植,因此谨慎使用,systemPath元素可以引用环境变量:
<dependency>
<groupId>javax.sql</groupId>
<artifactId>jdbc-stext</artifactId>
<version>2.0</version>
<scope>system</scope>
<systemPath>${java.home}/lib/rt.jar</systemPath>
</dependency>
6) import
不会对三种classpath产生影响,只能与dependencyManagement元素配合使用,其功能为将目标pom文件中dependencyManagement的配置导入合并到当前pom的dependencyManagement中
3.3 传递性
当存在间接依赖的情况,间接依赖的jar包的依赖范围只有为compile时,主工程才可以访问间接依赖。
四.maven依赖的原则和排除以及统一管理
4.1 maven依赖的原则
1). 路径最短者优先:
一个项目依赖了两个jar包,其中A-B-C-X(1.0) , A-D-X(2.0)。由于X(2.0)路径最短,所以项目使用的是X(2.0)
2). 路径相同先声明者优先
(声明的先后顺序指dependency标签配置的先后顺序) 如果A-B-X(1.0) ,A-C-X(2.0) 路径长度一样,maven会根据pom文件声明的顺序加载,如果先声明了B后声明了C,那依赖的是X(1.0)
3). 覆写优先
子pom内声明的优先于父pom
4.2 maven依赖的排除
exclusion标签
<dependency>
<groupId>cn.hutool</groupId>
<artifactId>hutool-all</artifactId>
<version>5.8.0.M3</version>
<!--依赖排除-->
<exclusions>
<exclusion>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.0</version>
<scope>test</scope>
</dependency>
4.3 maven统一管理目标jar的版本
设置properties属性,配置项目中依赖的版本:
<properties>
<webmagic.version>0.7.3</webmagic.version>
</properties>
在依赖中设置版本:
<dependency>
<groupId>us.codecraft</groupId>
<artifactId>webmagic-core</artifactId>
<version>${webmagic.version}</version>
</dependency>
4.4 仓库
(1)本地仓库:为本机上的所有Maven工程服务。
(2)远程仓库
a)私服:架设在当前局域网环境下,为当前局域网范围内的所有Maven工程服务
b)中央仓库:架设在Internet上,为全世界所有Maven工程服务
c)中央仓库的镜像:架设在各个大洲,为中央仓库分担流量,减轻中央仓库的压力
4.5 maven有三套相互独立的生命周期
Clean Lifecycle在进行真正的构建之前进行一些清理工作
Default Lifecycle构建的核心部分,编译,测试,打包,安装,部署
Site Lifecycle生成项目报告,站点,发布站点
五.继承
5.1 为什么需要继承机制
在依赖链中,非compile范围的依赖信息无法在依赖链中传递,如junit,使用继承机制可以将这样的依赖信息提取到父工程模块中进行统一管理
5.2 具体步骤
1). 创建父工程
创建父工程和创建一般工程操作一致,唯一需要注意的是,打包方式设置为pom,只需要保留pom.xml文件即可
2). 子工程中引入父工程
<parent>
<!-- 父工程坐标 -->
<groupId>...</groupId>
<artifactId>...</artifactId>
<version>...</version>
<!--指定从当前pom.xml文件出发寻找父工程的pom.xml文件的相对路径-->
<relativePath>..</relativePath>
</parent>
如果子工程的groupId和version和父工程重复则可删除
3). 在父工程管理依赖
将Parent项目中的dependencies标签,用dependencyManagement标签括起来
<dependencyManagement>
<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.0</version>
<scope>test</scope>
</dependency>
</dependencies>
</dependencyManagement>
在子项目中重新指定需要的依赖,删除范围和版本号
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
</dependency>
六.聚合
6.1 为什么需要聚合
将多个工程拆分为模块后,需要手动逐个安装到仓库后依赖才能生效。修改源码后需要逐个手动clean,而实用聚合后可以批量的进行maven工程的安装清理工作。
6.2 配置聚合
在总的聚合工程中,使用modules/module标签,指定模块工程的相对路径即可