Maven
学习笔记
【Maven
官网】https://maven.apache.org/
【Maven Repository
官网】https://mvnrepository.com/
零、参考教程
0.1、2021
最新Maven
教程-IDEA
版【看完】
【视频地址】https://www.bilibili.com/video/BV1Fz4y167p5
老师从底层(使用记事本)开始讲起,对于Maven
的入门和原理的理解很有帮助,并且声音很好听。美中不足是笔记的很多地方有笔误,并且讲解有的地方有点小错误(如打包多模块项目的步骤,应该是只要打包父项目即可)。
一、Maven
简介
1.1、总体知识结构
1.2、基本介绍
Apache Maven
的本质是一个软件项目管理和理解工具。基于项目对象模型 (Project Object Model,POM
) 的概念,Maven
可以通过一条中心信息,管理项目的构建、报告和文档。
Apache Maven is a software project management and comprehension tool. Based on the concept of a project object model (
POM
), Maven can manage a project's build, reporting and documentation from a central piece of information.
作为Apache
组织中的⼀个颇为成功的开源项目,Maven
主要服务于基于java
平台的项⽬构建,依赖管理和项目信息管理。
无论是小型的开源类库项目,还是大型的企业级应用;无论是传统的瀑布式开发,还是流行的敏捷开发,Maven
都能大显身手。
1.3、各类项目构建工具
1.1.1、Ant
最早的构建工具,大概是2000
年有的,是当时最流行Java
构建工具,不过它的XML
脚本编写格式让XML
文件特别大。对工程构建过程中的过程控制特别好。
1.1.2、Maven
项目对象模型(POM
),通过其描述信息来管理项目的构建、报告和文档的软件项目管理工具。它填补了Ant
缺点,Maven
第一次支持了从网络上下载的功能,仍然采用xml
作为配置文件格式。Maven
专注的是依赖管理,使用Java
编写。
1.1.3、Gradle
结合以上两者的优点,它继承了Ant
的灵活和Maven
的生命周期管理,它最后被google
作为了Android
御用管理工具。它最大的区别是不用XML
作为配置文件格式,采用了DSL
格式,使得脚本更加简洁。
【构建工具的选择】目前市面上
Ant
比较老,所以一般是一些比较传统的软件企业公司使用。Maven
使用Java
编写,是当下大多数互联网公司会使用的一个构建工具,中文文档也比较齐全。gradle
使用groovy
编写,是目前比较新型的构建工具。一些初创互联网公司会使用,以后会有很大的使用空间。
1.4、Maven
四大特性
1.4.1、依赖管理系统
Maven
为Java
引入了一个新的依赖管理系统(jar
包管理),jar
升级时修改配置文件即可。
可以使用groupId, artifactId, version
组成的坐标(Coordination
)唯一标识一个依赖。
任何基于Maven
构建的项目自身也必须定义这三项属性,生成的包可以是jar
包,也可以是war
包。
<!-- 依赖引用示例 -->
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
<version>3.1.0</version>
</dependency>
坐标属性:
Maven
坐标为各种组件引入了秩序,任何一个组件都必须明确定义自己的坐标。
groupId
:定义当前Maven
项目隶属的实际项目-公司名称(jar
包所在仓库路径)。由于Maven
中模块的概念,因此一个实际项目往往会被划分为很多模块。比如spring
是一个实际项目,其对应的Maven
模块会有很多,如spring-core, spring-webmvc
等。
artifactld
:该元素定义实际项目中的一个Maven
模块-项目名,推荐的做法是使用实际项目名称作为artifactld
的前缀。比如spring-bean, spring-webmvc
等。
version
:该元素定义Maven
项目当前所处的版本。
1.4.2、多模块构建
项目复查时dao service controller
层分离将一个项目分解为多个模块已经是很通用的一种方式。
在Maven中需要定义一个parent POM
作为一组module
的聚合POM
。在该POM
中可以使用标签来定义一组子模块。parent POM
不会有什么实际构建产出。而parent POM
中的build
配置以及依赖配置都会自动继承给child module
。
1.4.3、—致的项目结构
Ant
时代大家创建Java
项目目录时比较随意,然后通过Ant
配置指定哪些属于source
,哪些属于testSource
等。
而Maven
在设计之初的理念就是Conversion over configuration
(约定大于配置),其制定了一套项目目录结构作为标准的Java
项目结构,解决不同ide
带来的文件目录不一致问题。
1.4.4、⼀致的构建模型和插件机制
在编写 JavaWeb
项目时需要使用类似 tomcat
的服务器,我们可以通过插件的形式将服务器引入进来。
例如,如果需要使用 jetty
的服务器,可以通过下面的配置将 jetty
服务器引入进来。
<plugin>
<groupId>org.mortbay.jetty</groupId>
<artifactId>maven-jetty-plugin</artifactId>
<version>6.1.25</version>
<configuration>
<scanIntervalSeconds>10</scanIntervalSeconds>
<contextPath>/test</contextPath>
</configuration>
</plugin>
二、Maven
安装配置
【注意】安装
maven
需提前安装jdk
环境,详见java笔记.md
。
2.1、Maven
下载
进入官网下载地址(https://maven.apache.org/download.cgi),选择合适的版本。
直接点击链接下载,或者可以使用wget
命令下载。
wget https://dlcdn.apache.org/maven/maven-3/3.9.5/binaries/apache-maven-3.9.5-bin.tar.gz
解压下载好的压缩包,并移动到合适的目录。
# 解压压缩包
tar -zxvf apache-maven-3.9.5-bin.tar.gz
# 移动文件夹到合适的位置(可选)
mv apache-maven-3.9.5 ~/maven/
2.2、配置环境变量
把Maven
的根目录配置到系统环境变量MAVEN_HOME
中,将bin
目录配置到path
变量中。
【注】maven
解压后存放的目录不要包含中文和空格。
vim /etc/profile
# 在环境变量部分修改如下内容 仅需要新增注释标记的部分 其他部分为原有配置
export JAVA_HOME=/usr/local/java/jdk-11.0.21
export MAVEN_HOME=/usr/local/maven # 新增
export PATH=$PATH:$JAVA_HOME/bin:$MAVEN_HOME/bin # 新增 $MAVEN_HOME/bin
刷新使配置文件生效。
source /etc/profile
2.4、检查安装成功
使用如下命令检查是否安装配置成功。
mvn -v
2.5、本地仓库和镜像配置
配置本地仓库和阿里云镜像。
cd ~/maven/ # 进入maven目录
mkdir repo # 创建目录 repo
# 编辑conf/settings.xml 文件
vim conf/settings.xml
# 添加本地仓库配置
<localRepository>/usr/local/maven/repo</localRepository>
# Windows 的地址示例 D:/m2/repository(如果不修改,默认在 C 盘用户目录中的 .m2 目录下)
# 注释掉原本的镜像,添加阿里云镜像
<mirror>
<id>alimaven</id>
<name>aliyun maven</name>
<url>http://maven.aliyun.com/nexus/content/groups/public/</url>
<mirrorOf>central</mirrorOf>
</mirror>
# 注:如果需要通过代理才能联网,则还需要配置代理
<proxy>
<id>optional</id>
<active>true</active>
<protocol>http</protocol>
<!-- <username></username> -->
<!-- <password></password> -->
<host>10.26.2.36</host>
<port>8981</port>
<!-- <nonProxyHosts>10.26.2.**</nonProxyHosts> -->
</proxy>
三、创建Maven
项目
3.1、Maven
项目目录结构
3.2、编译并运行
进入项目的根目录,执行以下命令。
mvn compile # 编译 java 文件(成功会提示 BUILD SUCCESS)
mvn exec:java -Dexec.mainClass="com.xxxx.demo.Hello" # 执⾏指定 java 类文件的 main ⽅法
四、常用Maven
命令
作为开发利器的maven
,为我们提供了十分丰富的命令,了解maven
的命令行操作并熟练运用常见的maven
命令是十分必要的。虽然IDEA
等工具提供了图形界面化工具,但其底层还是依靠maven
命令来驱动的。
Maven
的命令格式如下:
# 执行 plugin-name 插件的 goal-name 目标
mvn [plugin-name]:[goal-name]
4.1、常用命令
命令 | 描述 |
---|---|
mvn -version | 显示版本信息 |
mvn clean | 清理项目产生的临时文件,一般是模块下的target 目录 |
mvn compile | 编译源代码,一般编译模块下的src/main/java 目录 |
mvn package | 项目打包命令,会在模块下的target 目录生成jar 或者war 等文件 |
mvn test | 测试命令,执行src/test/java/ 下的junit 测试用例 |
mvn install | 将打包的jar 或war 文件复制到你的本地仓库中,供其他模块使用 |
mvn deploy | 将打包的文件发布到远程参考,供其他人进行下载依赖 |
mvn site | 生成项目相关信息的网站 |
mvn eclipse:eclipse | 将项目转化为Eclipse 项目 |
mvn dependency:tree | 打印出项目的整个依赖树 |
mvn archetype:generate | 创建Maven 的普通java 项目 |
mvn tomcat7:run | 在tomcat 容器中运行web 应用 |
mvn jetty:run | 调用Jetty 插件的Run 目标在Jetty Servelet 容器中启动web 应用 |
【注意】运行
maven
命令的时候,首先需要定位到maven
项目的目录,也就是项目的pom.xml
文件所在的目录。否则,必须通过参数来指定项目的目录。
4.2、命令参数
上面列举的只是比较通用的命令,其实很多命令都可以携带参数以执行更精准的任务。
4.2.1、-D
传入属性参数
使用示例如下:
mvn package -Dmaven.test.skip=true
以-D
开头,将maven.test.skip
的值设为true
,就是告诉maven
打包的时候跳过单元测试。同理,mvn deploy-Dmaven.test.skip=true
代表部署项目并跳过单元测试。
4.2.2、-P
使用指定的profile
配置
比如项目开发需要有多个环境,一般为开发、测试、预发、正式4个环境,在pom.xml
中的配置如下:
<profiles>
<profile>
<id>dev</id>
<properties>
<env>dev</env>
</properties>
<activation>
<activeByDefault>true</activeByDefault>
</activation>
</profile>
<profile>
<id>qa</id>
<properties>
<env>qa</env>
</properties>
</profile>
<profile>
<id>pre</id>
<properties>
<env>pre</env>
</properties>
</profile>
<profile>
<id>prod</id>
<properties>
<env>prod</env>
</properties>
</profile>
</profiles>
......
<build>
<filters>
<filter>config/${env}-properties</filter>
</filters>
<resources>
<resource>
<directory>src/main/resources</directory>
<filtering>true</filtering>
</resource>
</resources>
</build>
profiles
定义了各个环境的变量id
,filters
中定义了变量配置文件的地址,其中地址中的环境变量就是上面profile
中定义的值,resources
中是定义哪些目录下的文件会被配置文件中定义的变量替换。
通过maven
可以实现按不同环境进行打包部署,例如:
mvn package -Pdev -Dmaven.test.skip=true # 打包本地环境,并跳过单元测试
五、IDEA
集成Maven
环境
5.1、环境配置
找到IDEA
中的如下位置。
配置好如下三个选项,点击Apply
。
设置自动导入Maven
依赖。
5.2、创建Maven
项目
5.2.1、Java
项目
5.2.1.1、创建项目
选择File -> New -> Project
。可以选择quickstart
模板,或者直接不选即可。
设置项目的groupId
和artifactId
。
检查Maven
环境,选择Next
。
检查项目名和工作空间,选择Finish
。
等待项目创建,下载资源,完成后目录结构如下。
【注意】
1、右下角弹出的提示框,选择"
Enable Auto-Import
"(Maven
启动自动导入)2、
Maven
的版本高于IDEA
版本,创建Maven
项目时可能会出现报错。解决方法:使用IDEA
默认的Maven
等。
5.2.1.2、编译项目
点击右上角的添加配置(或者直接使用IDEA
右边的Maven
窗口执行)。
选择Maven
配置。
设置编译项目的命令。
执行编译命令,两个图标分别代表普通模式和调试模式。
编译成功。
5.2.2、Web
项目
5.2.2.1、创建项目
创建Web
项目与创建Java
项目步骤基本一致,区别在于Maven
模板选择webapp
。
创建完成后,项目的目录结构如下。
5.2.2.2、项目配置
根据自己的需要修改JDK
的版本。
<!-- JDK的版本修改为1.8 -->
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<maven.compiler.source>1.8</ maven.compiler.source>
<maven.compiler.target>1.8</ maven.compiler.target>
</properties>
设置junit
的版本。
<!-- junit的版本修改为4.12 -->
<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
<scope>test</scope>
</dependency>
</dependencies>
删除pluginManagement
标签。
<!-- 将这个标签及标签中的内容全部删除 -->
<pluginManagement>
...
</pluginManagement>
添加web
部署的插件(在build
标签中)。
【注】下述配置Jetty
和Tomcat
任选其一即可。
<plugins>
<!-- Jetty 插件(轻量级的服务器) -->
<plugin>
<groupId>org.mortbay-jetty</groupId>
<artifactId>maven-jetty-plugin</artifactId>
<version>6.1.25</version>
<configuration>
<!-- 热部署,每 10 秒扫描一次 -->
<scanIntervalseconds>10</scanIntervalseconds>
<!-- 可指定当前项目的站点名 -->
<contextPath>/test</contextPath>
<connectors>
<connector implementation="org.mortbay.jetty.nio.selectChannelConnector">
<!-- 设置启动的端口号 -->
<port>9090</ port>
</connector>
</connectors>
</configuration>
</plugin>
<!-- Tomcat 插件 -->
<plugin>
<groupId>org-apache.tomcat.maven</groupId>
<artifactId>tomcat7-maven-plugin</artifactId>
<version>2.1</version>
<configuration>
<!-- 启动端口默认:8080 -->
<port>8080</port>
<!-- 项目的站点名,即对外访问路径 -->
<path>/test</path>
<!--字符集编码默认︰ISO-8859-1 -->
<uriEncoding>UTF-8</uriEncoding>
<!--服务器名称-->
<server>tomcat7</server>
</configuration>
</plugin>
</plugins>
5.2.2.3、启动项目
添加jetty
插件配置。
上述命令中,也可以在命令中直接指定端口。
jetty:run -Djetty.port=9090 # 需要将插件配置中的 port 标签去掉
也可以添加Tomcat
插件配置。
启动成功后浏览器访问8080
端口即可看到效果。
六、Maven
仓库
当第一次运行Maven
命令的时候,你需要Internet
链接,因为它需要从网上下载一些文件。那么它从哪里下载呢?它是从Maven
默认的远程库下载的。这个远程仓库有Maven
的核心插件和可供下载的jar
文件。
对于Maven
来说,仓库只分为两类:本地仓库和远程仓库。
当Maven
根据坐标寻找构件的时候,它首先会查看本地仓库,如果本地仓库存在,则直接使用;如果本地没有,Maven
就会去远程仓库查找,发现需要的构件之后,下载到本地仓库再使用。如果本地仓库和远程仓库都没有,Maven
就会报错。
远程仓库分为三种:中央仓库,私服,其他公共库。
- 中央仓库是默认配置下,
Maven
下载jar
包的地方。 - 私服是另一种特殊的远程仓库,为了节省带宽和时间,可以在局域网内架设一个私有的仓库服务器,用其代理所有外部的远程仓库。内部的项目还能部署到私服上供其他项目使用。
一般来说,在Maven
项目目录下,没有诸如lib/
这样用来存放依赖文件的目录。当Maven
在执行编译或测试时,如果需要使用依赖文件,它总是基于坐标使用本地仓库的依赖文件。
默认情况下,每个用户在自己的用户目录下都有一个路径名为.m2/repository/
的仓库目录。有时候,因为某些原因(比如c
盘空间不足),需要修改本地仓库目录地址。
6.1、中央仓库
由于原始的本地仓库是空的,maven
必须知道至少一个可用的远程仓库,才能在执行maven
命令的时候下载到需要的构件。中央仓库就是这样一个默认的远程仓库。
中央仓库包含了2000
多个开源项目,接收每天1
亿次以上的访问。
6.2、私服
私服是一种特殊的远程仓库,它是架设在局域网内的仓库服务,私服代理广域网上的远程仓库,供局域网内的maven
用户使用。当maven
需要下载构件时,它去私服当中找,如果私服没有,则从外部远程仓库下载,并缓存在私服上,再为maven
提供。
此外,一些无法从外部仓库下载的构件也能从本地上传到私服提供局域网中其他人使用。
使用私服的好处:1、节省外网带宽;2、加速maven
构建;3、部署第三方控件;4、提高稳定性;5、降低中央仓库的负荷。
项目的pom.xml
配置示例:
<repositories>
<repository>
<snapshots>
<enabled>true</enabled>
</snapshots>
<id>public</id>
<name>Public Repositories</name>
<url>http://192.168.0.96:8081/content/groups/public/</url>
</repository>
<repository>
<id>getui-nexus</id>
<url>http://mvn.gt.igexin.com/nexus/content/repositories/releases/</url>
</repository>
</repositories>
6.3、其他公共库
常用的阿里云仓库配置。
<mirror>
<id>nexus-aliyun</id>
<mirrorOf>central</mirrorOf>
<name>Nexus aliyun</name>
<url>http://maven.aliyun.com/nexus/content/groups/public</url>
</mirror>
七、Maven
中构建多模块项目
使用maven
提供的多模块构建的特性,完成maven
环境下多模块项目的管理与构建。
这里以四个模块为例来搭建项目。
模块 maven_parent —— 基模块,就是常说的 parent (pom)
模块 maven_dao —— 数据库的访问层,例如 jdbc 操作 (jar)
模块 maven_service —— 项目的业务逻辑层 (jar)
模块 maven_controller —— 用来接收请求,响应数据 (war)
7.1、创建项目和模块
7.1.1、创建maven_parent
项目
新建一个Maven
项目。
设置groupId
和artifactId
。
确认项目名称和工作空间。
7.1.2、创建maven_dao
模块
选择项目maven_parent
,右键新建模块。
选择maven
的普通java
项目。
7.1.3、创建maven_service
模块
创建步骤同maven_dao
模块。
7.1.4、创建maven_controller
模块
创建步骤基本同maven_dao
模块,只需将模板修改为web
项目模板即可。
7.1.5、检查模块创建和修改配置文件
模块全部创建完毕后,效果如下:
可以修改各个子模块对应的配置文件。
7.2、设置模块之间的依赖
7.2.1、maven_dao
模块
新建包文件夹。
新建UserDao
类。
package com.xxxx.dao;
public class UserDao {
public static void testDao () {
system.out.println ( "UserDao Test...");
}
}
7.2.2、maven_service
模块
添加maven_dao
模块的依赖。
<!-- 加入 maven_dao 模块的依赖 -->
<dependency>
<groupId>com.xxxx</groupId>
<artifactId>maven_dao</artifactid>
<version>1.0-SNAPSHOT</version>
</dependency>
新建UserService
类。
package com.xxxx.service;
import com.xxxx.dao.UserDao;
public class Userservice {
public static void testservice() {
system.out.println("UserService Test...");
// 调用 UserDao 的方法
UserDao.testDao();
}
}
7.2.3、maven_controller
模块
添加maven_service
模块的依赖。
<!-- 加入 maven_service 模块的依赖 -->
<dependency>
<groupId>com.xxxx</groupId>
<artifactId>maven_service</artifactId>
<version>1.0-SNAPSHOT</version>
</dependency>
添加servlet
的依赖。
<!-- servlet 的依赖 -->
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactid>
<version>3.0.1</version>
<scope>provided</scope>
</dependency>
添加Tomcat
插件,参见5.2.2
节。
创建UserServlet
类(如果main
目录下没有java
源文件夹,可以自己手动创建,并指定为Sources Root
类型文件夹)。
package com.xxxx.controller;
import com.xxxx.service.Userservice;
import javax.servlet.servletException;
import javax.servlet.annotation.webServlet;
import javax.servlet.http.Httpservlet;
import javax.servlet.http.HttpservletRequest;
import javax.servlet.http.HttpservletResponse;
import java.io.IOException;
@webServlet("/user")
public class UserServlet extends Httpservlet {
@override
protected void service(HttpServletRequest req, HttpServletResponse resp) throws servletException, IOException {
system.out.println("Userservlet Test...");
// 调用 UserService 层的方法
Userservice.testservice();
}
使用快捷键
Ctrl+o
可以打开选择override
方法的菜单。
7.2.4、安装模块
安装顺序为,先install
父项目,如果有出错再单独install
出错的子项目。
install maven
项目时,右侧maven->lifecircle
直接选中双击更加方便。
7.2.5、启动项目
配置如下运行命令。
启动成功后,可以通过网址访问项目。控制台输出如下:
八、Maven
的打包操作
对于企业级项目,无论是进行本地测试,还是测试环境测试,以及最终的项目上线,都会涉及项目的打包操作。对于每个环境下的项目打包时,对应的项目所需要的配置资源都会有所区别,实现打包的方式有很多种:可以通过ant
,或者通过IDEA
自带的打包功能实现项目的打包,但当项目很大并且需要的外界配置很多时,此时打包的配置就会异常复杂。
对于maven
项目,我们可以用pom.xml
配置的方式来实现打包时的环境选择,相比于其他的打包工具,maven
只需要通过简单的配置,就可以轻松完成不同环境下项目的整体打包。
比如下面这样一个项目,项目中配置了不同环境下所需要的配置文件,需要完成不同环境下的打包操作。
8.1、准备好一个项目
使用idea
创建项目,目录结构可能会缺失,需要手动添加对应的目录(也可在创建时直接勾选对应的文件夹)。
以下展示了一个基本的web
项目所具有的项目结构。
添加不同环境对应的文件夹和相关的配置文件。
8.2、添加profile
配置
在项目的pom.xml
文件中添加如下配置。
<!-- 打包环境配置: 开发环境 测试环境 正式环境 -->
<profiles>
<profile>
<id>dev</id>
<properties>
<env>dev</env>
</properties>
<!-- 未指定环境时,默认打包 dev 环境 -->
<activation>
<activeByDefault>true</activeByDefault>
</activation>
</profile>
<profile>
<id>test</id>
<properties>
<env>test</env>
</properties>
</profile>
<profile>
<id>product</id>
<properties>
<env>product</env>
</properties>
</profile>
</profiles>
8.3、添加资源文件配置
在项目的pom.xml
文件中的<build>
标签内添加如下配置。
<!-- 对于项目资源文件的配置,放在 build 中-->
<resources>
<resource>
<directory>src/main/resources/${env}</directory>
</resource>
<resource>
<directory>src/main/java</directory>
<includes>
<include>**/*.xml</include>
<include>**/*.properties</include>
<include>**/*.tld</include>
</includes>
<filtering>false</filtering>
</resource>
</resources>
8.4、执行打包操作
打开IDEA
的命令配置页面,输入打包命令。
运行后打包成功。
不同的项目打包得到的文件不一样,一般来说,普通java
项目打成jar
包,web
项目打成war
包。
九、Maven
依赖
9.1、依赖的基本配置
根元素project
下的dependencies
可以包含多个dependency
元素,以声明多个依赖。每个依赖都应该包含以下元素:
1、groupld, artifactld, version
:依赖的基本坐标,对于任何一个依赖来说,基本坐标是最重要的,Maven
根据坐标才能找到需要的依赖。
2、Type
:依赖的类型,大部分情况下不需要声明。默认值为jar
。
3、Scope
:依赖范围(compile, test, provided, runtime, system
)
-
compile
:编译依赖范围。如果没有指定,就会默认使用该依赖范围。使用此依赖范围的Maven依赖,对于编译、测试、运行三种
classpath
都有效。 -
test
:测试依赖范围。使用此依赖范围的
Maven
依赖,只对于测试classpath
有效,在编译主代码或者运行项目的使用时将无法使用此类依赖。典型的例子就是JUnit
,它只有在编译测试代码及运行测试的时候才需要。 -
provided
:已提供依赖范围。使用此依赖范围的
Maven
依赖,对于编译和测试classpath
有效,但在运行时无效。典型的例子是servlet-api
,编译和测试项目的时候需要该依赖,但在运行项目的时候,由于容器已经提供,就不需要Maven
重复地引入一遍。 -
runtime
:运行时依赖范围。使用此依赖范围的
Maven
依赖,对于测试和运行classpath
有效,但在编译主代码时无效。典型的例子是JDBC
驱动程序,项目主代码的编译只需要JDK
提供的JDBC
接口,只有在执行测试或者运行项目的时候才需要实现上述接口的具体JDBC
驱动。 -
system
:系统依赖范围。该依赖和
provided
依赖范围完全一致。但是,使用system
范围依赖时必须通过systemPath
元素显式地指定依赖文件的路径。由于此类依赖不是通过Maven
仓库解析的,而且往往与本机系统绑定,可能造成构建的不可移植,因此应该谨慎使用。
4、Optional
:标记依赖是否可选。<optional>
标签被设置为true
,表示该依赖项是可选的。开发者可以根据实际需要选择是否包含该依赖项。值得注意的是,optional
标签不仅适用于直接依赖项,还可以用于传递性依赖项。这意味着如果一个项目依赖于一个可选的库,而该库又依赖于另一个库,那么只有当直接引用该库时,其传递性依赖项才会被包含进来。这对于避免不必要的传递性依赖和潜在的版本冲突非常有用。
5、Exclusions
:用来排除传递性依赖。使用示例如下9.3
节。
9.2、依赖范围
Maven
在编译、测试、运行项目的时候,往往会用到多套不同的classpath
。
例如:编译项目代码的时候需要用到spring-core
,该文件以依赖的方式被引入到编译环境的classpath
中;而测试项目的时候,可能会用到另一套classpath
,其包含junit
。而在运行项目的环境中,使用的classpath
包括spring-core
,而不包括junit
。
依赖范围就是用来控制依赖与这三种classpath
(编译classpath
,测试classpath
,运行classpath
)的关系,Maven
的具体依赖范围及说明见上一小节。
9.3、传递性依赖
传递依赖机制,让我们在使用某个jar
的时候就不用去考虑它依赖了什么,也不用担心引入多余的依赖。
Maven
会解析各个直接依赖的POM
,将那些必要的间接依赖,以传递性依赖的形式引入到当前项目中。
【注意】传递依赖有可能产生冲突!!
# 冲突场景
A --> B --> C (2.0)
A --> D --> C (1.0)
如果A
同时依赖两个不同version
的C
,冲突!需要选取同时适合A、D
的版本。
<dependencies>
<dependency>
<groupId>A</groupId>
<artifactId>A</artifactId>
<version>xxx</version>
<exclusions>
<!-- 排除 A 依赖的 C -->
<exclusion>
<groupId>C</groupid>
<artifactId>C</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>B</groupId>
<artifactId>B</artifactid>
</dependency>
</dependencies>
9.4、依赖覆盖
默认情况下,自定义的Maven
依赖的版本会优先覆盖传递依赖的Maven
依赖的版本。
9.5、依赖图展示
IDEA
中,可以在pom.xml
文件中右键,选择Show Diagraphs
来直观地展示依赖图和依赖链。
9.6、依赖继承
待后续记录。
评论区