Maven基础篇
Maven基础篇
主要内容
1、Maven的简介
1.1 什么是Maven
Maven[ˈmeɪvn],这个词可以翻译为“专家、内行”,是一个项目管理工具,可以对 Java 项目进行自动化的构建和依赖管理。
它包含了:项目对象模型 (POM,Project Object Model),项目生命周期(Project Lifecycle),依赖管理系统(Dependency Management System)和各种插件。插件主要用来实现生命周期各个阶段(phase)的目标(goal)。Maven的组成如下所示:
1.2 传统开发的痛点
1、我们需要在工程中引用各种 jar 包,尤其是比较大的工程,引用的 jar 包往往有几十个乃至上百个, 每用到一种 jar 包,都需要手动引入到工程的lib目录,而且经常遇到各种让人抓狂的 jar 包冲突。
2、当新人接手一个项目时,就需要把项目中所有的依赖都下载到自己电脑上,非常麻烦,不同项目可能存在相同的依赖包,非常占电脑存储空间。
3、构建(build)是每个程序员每天都在做的事情,早上来到公司,第一件事就是从源码库中签出最新的代码,然后单元测试,如果测试失败,会找相关同事一起调试,修复代码。然后再回到自己的工作上来,编写自己的单元测试和产品代码。而Maven提供了只需要运行一条简单的命令,就能完成重复的,繁琐的构建和测试动作。
总结一下,我们会发现我们每天相当一部分时间花在了编译、运行单元测试、生成文档、打包和部署等繁琐且不起眼的工作上了,Maven能够是我们从这种繁琐的工作中解脱出来,只需要一条命令所有繁琐的步骤都能够自动完成。
1.3 项目构建工具的历史
Ant -> Maven -> Gradle
1、Ant
说起Ant,就不得不说另一个Apache开源项目Tomcat。Tomcat作为轻量级Web容器,早已声名鹊起。最开始的时候,Ant是Tomcat的一部分,Ant的唯一目的就是build Tomcat。
不久,很多Java开源项目意识到Ant的简洁适用,更重要的是弥补Makefiles的不足。自从Jakarta以及Apache项目开始采用Ant以来,作为构建工具的Ant很快发展在各种各样的项目中。
在2000年1月,Ant脱离了Tomcat,成为独立的Apache开源项目,由独立的CVS模块维护,正式更名为Apache Ant。
Ant实例:
1 |
|
由示例,得知Ant定义了五个任务,init, compile, build, test,clean。
每个任务做什么都定义清楚了。在打包之前要先编译,所以通过depends来指定依赖的路径。
如果在命令行里执行ant build,那就会先执行compile,而compile又依赖于init,所以就会先执行init。
1 | ant test |
通过命令就可以执行编程,打包,测试。为开发者带来了很大的便利,提供了工作效率。
但是Ant有一个很致命的缺陷,那就是没办法管理依赖。每次打包都需要手动将正确的依赖拷贝到lib
目录中去,这个工作不仅枯燥还容易出错,为了解决这个问题Maven
如约而至。
2、Maven
aven之前我们经常使用Ant来进行Java项目的构建,然后Ant仅是一个构建工具,它并未对项目的中的工程依赖以及项目本身进行管理,并且Ant作为构建工具未能消除软件构建的重复性,因为不同的项目需要编写对应的Ant任务。
Maven作为后来者,继承了Ant的项目构建功能,并且提供了依赖关系,项目管理的功能,因此它是一个项目管理和综合工具。
Maven 发展历程: Maven –> Maven2 –> Maven3
Maven示例:
1 |
|
相对于Ant
来说,Maven
抛弃了Ant
中通过target
定义任务的做法,对于依赖引入了生命周期。
3、Gradle
Gradle是一个基于Apache Ant和ApacheMaven概念的项目自动化构建开源工具。它使用一种基于Groovy的特定领域语言(DSL)来声明项目设置,目前也增加了基于Kotlin语言的kotlin-based DSL,抛弃了基于XML的各种繁琐配置。
由以上定义得知,Gradle已经抛弃了Ant,Maven中Xml配置的形式。Gradle继承了Maven中仓库,坐标,依赖这些核心概念。文件的布局也和Maven相同。但同时,又继承了Ant中target的概念,我们又可以重新定义自己的任务(在Gradle中叫做task)。
Gradle示例:
1 | apply plugin: 'java' |
1.4 Maven的四大特性
1、依赖管理
Maven 为 java 世界引入了一个新的依赖管理系统:jar 包管理。当需要使用某个 jar 包时,不需要再从网络上下载并导入了,只需要配置其依赖即可;而当 jar 包需要升级时,也不需要重新下载最新的包并重新导入,只要修改 pom.xml 配置文件即可。在 java 世界中,可以用 groupId、artifactId、version 组成的 Coordination(坐标)唯一标识一个依赖。
同时,任何基于 Maven 构建的项目自身也必须定义这三项属性,生成的包可以是 jar 包,也可以是 war 包。一个典型的依赖引用如下所示:
1 | <dependency> |
2、多模块构建(聚合与继承)
项目复查时,使用将 dao、service、controller 层分离的方式,将一个项目分解为多个模块已经是一个很通用的方式。
在 Maven 中需要定义一个 parent POM 作为一组 module
的聚合 POM。在该 POM 中可以使用 <modules>
标签来定义一组子模块。parent POM 不会有什么实际构建产出,而 parent POM 中的 build 配置以及依赖配置都会自动继承给子模块。
3、一致的项目结构
在 Ant 时代,大家创建 java 项目目录时比较随意,然后通过 Ant 配置指定哪些属于 source,哪些属于 test source等。并且,不同的 IDE (IDEA和Eclipse)创建项目时,目录结构是不一样的,这就会导致两种 IDE 的项目不能兼容导入。而 Maven 在设计之初的理念就是 “Conversion over configuration”(约定大于配置),其制定了一套统一的项目目录结构作为标准的 java maven 项目结构,解决了不同 IDE 带来的文件目录不一致问题,只要是 Maven 项目,在各个 IDE 中建立的项目结构都是一样的。
4、一致的构建模型和插件机制
在编写 JavaWeb 项目时需要使用类似 tomcat
的服务器,我们可以通过插件的形式将服务器引入进来。如果需要使用 jetty
的服务器,也可以通过插件的形式将 jetty
服务器引入进来。
tomcat
服务器插件:
1 | <plugin> |
jetty
服务器插件:
1 | <plugin> |
2、Maven的安装配置和目录结构
2.1 安装配置
2.1.1 下载Maven
官网下载Maven:http://maven.apache.org/download.html
选择版本: apache-maven-3.8.3-bin.zip
2.1.2 配置环境变量
解压后,新建一个
MAVEN_HOME
系统变量,把Maven根目录配置到该系统变量中。系统变量
PATH
中,新增一条%MAVEN_HOME%\bin
注:maven解压后存放的目录不要包含中文或空格。
测试是否配置成功
win+R
打开cmd
窗口,键入mvn -v
,弹出如下信息则是配置成功,若提示不是内部或外部命令,也不是可运行的程序 或批处理文件。
则是环境变量配置存在问题。配置字符编码为
UTF-8
默认字符编码为
GBK
新建一条系统环境变量
MAVEN_OPTS
值设置为-Xms256m -Xmx512m -Dfile.encoding=UTF-8
重新打开一个命令行窗口,键入mvn -v
,如果显示platform encoding:UTF-8
,则是配置成功。
2.1.3 配置远程仓库
打开maven
目录中的conf/setting.xml
文件,找到<mirrors>
标签,将其中的默认镜像配置删除或注释,更改为阿里云的仓库地址。
1 | <mirrors> |
默认仓库源在国外,速度比较慢。
2.1.4 配置JDK版本
配置JDK
版本为1.8
打开maven
目录中的conf/setting.xml
文件,在<profiles>
标签中配置如下内容:
1 | <profile> |
2.2 Maven目录结构
maven
统一了目录结构,不论是在eclipse
还是idea
,都能够成功导入并编译运行。
maven
的项目结构如下表:
目录 | 功能 |
---|---|
${basedir} | 存放pom.xml和所有的子目录 |
${basedir}/src/main/java | 存放项目中java源代码 |
${basedir}/src/main/resource | 存放项目中的资源文件,比如db.properties等 |
${basedir}/src/test/java | 存放项目中测试类的代码,比如JUnit代码 |
${basedir}/src/test/resource | 存放测试使用的资源文件 |
2.2.1 手动创建以上目录并编译
- 选择一个位置创建目录名为
maven-hello
的项目。
创建完成目录结构如图。
向
pom.xml
文件添加内容,内容如下。1
2
3
4
5
6
7
8
9
10
<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">
<modelVersion>4.0.0</modelVersion>
<groupId>cn.yuencode</groupId>
<artifactId>maven-hello</artifactId>
<version>1.0-SNAPSHOT</version>
</project>编写主函数
1 | package cn.yuencode.mavenhello; |
编译
命令行进入
maven-hello
根目录执行命令
1
mvn compile # 编译
第一次执行需要下载依赖,需要一段时间。
运行
执行命令
1
mvn exec:java -Dexec.mainClass="cn.yuencode.mavenhello.Hello"
3、IDEA集成maven环境
选择 “File” —> “New Projects Settings” —> “Settings for New Projects…” —> 搜索 “Maven
选择本地Maven路径:
配置settings.xml
和本地仓库路径:
4、Maven项目的创建
4.1 Java项目
4.1.1 新建项目
- 选择
File
->New
->Project
,选择Maven
,选择版本为1.8的JDK - 选择从骨架创建,并选择骨架
org.apache.maven.archetypes:maven-archetype-quickstart
定义项目名称、GroupId、ArtifactId、Version
配置Maven,如果与设置中的一致,点击Finish即可。
等待完成后,查看目录
有时候目录并没有创建完整,这时候需要我们手动创建一下,如下图,资源目录没有被创建,我们需要手动创建一下资源目录
注意,目录创建成功后需要标记为资源目录
4.1.2 编译项目
添加配置
创建一条compile命令
执行命令
分为
普通模式
和调试模式
。编译成功
4.2 Web项目
4.2.1 新建项目
勾选从骨架创建,选择骨架
org.apache.maven.archetypes:maven-archetype-webapp
定义项目名称等信息
项目目录结构
4.2.2 启动项目
修改pom.xml中jdk版本为1.8或其它对应版本
1
2
3
4
5<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>设置单元测试版本
1
2
3
4
5
6
7
8
9<dependencies>
<!-- Junit版本修改为4.12 -->
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
<scope>test</scope>
</dependency>
</dependencies>删除pluginManagement标签
1
2
3
4<!-- 将这个标签及标签中的内容全部删除 -->
<pluginManagement>
...
</pluginManagement>添加web部署插件
1
2
3
4
5
6<build>
<plugins>
<plugin>
</plugin>
</plugins>
</build>tomcat插件
1
2
3
4
5
6
7
8
9
10
11
12<!-- Tomcat插件 -->
<plugin>
<groupId>org.apache.tomcat.maven</groupId>
<artifactId>tomcat7-maven-plugin</artifactId>
<version>2.1</version>
<configuration>
<port>8081</port> <!-- 启动端口 默认:8080 -->
<path>/maven02</path> <!-- 项目的站点名,即对外访问路径 -->
<uriEncoding>UTF-8</uriEncoding> <!-- 字符集编码 默认:ISO-8859-1 -->
<server>tomcat7</server> <!-- 服务器名称 -->
</configuration>
</plugin>jetty插件
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15<!-- jetty插件 -->
<plugin>
<groupId>org.eclipse.jetty</groupId>
<artifactId>jetty-maven-plugin</artifactId>
<version>9.4.5.v20170502</version>
<configuration>
<httpConnector>
<port>8000</port><!-- 设置启动的端口号 -->
</httpConnector>
<webApp> <!-- 可指定当前项目的站点名 -->
<contextPath>/maven02</contextPath>
</webApp> <!-- 热部署,每10秒扫描一次 -->
<scanIntervalSeconds>10</scanIntervalSeconds>
</configuration>
</plugin>配置中添加命令
mvn tomcat7:run
与mvn jetty:run
或直接运行命令。
5、Maven命令
作为开发利器的maven
,为我们提供了十分丰富的命令,了解maven
的命令行操作并熟练运用常见的maven
命令还是十分必要的,即使譬如IDEA等工具给我提供了图形界面化工具,但其底层还是依靠maven
命令来驱动的。
Maven
的命令格式如下:
1 | mvn [plugin-name]:[goal-name] |
命令代表的含义:执行 plugin-name
插件的goal-name
目标
4.1 常用命令
命令 | 描述 |
---|---|
mvn -version | 显示maven版本信息 |
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 servlet容器中启动web应用 |
注意:运行maven命令时,需要定位到maven项目的目录,即项目的pom.xml文件所在的目录,否则需要通过参数指定项目的目录。但有些命令则不需要比如
mvn archetype:generate
5.2 命令参数
maven很多命令都可以携带参数以执行更精确的任务。
5.2.1 -D 传入属性参数
mvn package -Dmaven.test.skip=true
以-D
开头传入属性参数,将maven.test.skip
的值设置为true
,即maven在打包时会跳过单元测试。同理,mvn deploy -Dmaven.test.skip=true
表示部署项目跳过但单元测试。
5.2.2 -P 使用指定的Profile配置
一般在项目开发中需要有多个环境,比如开发、测试、预发、正式4个环境。
我们可以通过配置pom.xml,在不同环境中使用不同的配置文件。
1 | <profiles> |
具体操作步骤见6.2 多环境打包
6、Maven的打包操作
对于企业级项目,无论是进行本地测试,还是测试环境测试以及最终的项目上线,都会涉及到项目的打包操作。对于不同环境下项目的打包,对应项目的配置文件都会有所不同,实现打包的方式有很多种,可以通过ant、或者idea自带的打包功能实现项目打包,但当项目很大并且需要的外界配置很多时,此时打包的配置就会异常复杂,对于Maven项目,我们可以通过pom.xml
配置的方式实现打包时环境的选择,相比较其他形式打包工具,通过Maven只需要简单的配置,就可以轻松完成不同环境下项目的整体打包。
6.1 补全目录结构
使用idea创建项目,目录结构可能会缺失,这时需要我们手动添加对应的目录。
补全目录后项目结构
6.2 多环境打包
6.2.1 添加不同环境的配置文件
内容分别为
dev(开发环境)
bean.xml
1
2
3<bean>
dev
</bean>db.properties
1
2jdbc.username=root
jdbc.password=123456test(测试环境)
bean.xml
1
2
3<bean>
test
</bean>db.properties
1
2jdbc.username=test123
jdbc.password=666666prod(product生成环境)
bean.xml
1
2
3<bean>
prod
</bean>db.properties
1
2jdbc.username=prod
jdbc.password=daghi9aeghawgaej9
6.2.2 pom.xml中添加profile配置
1 | <!-- 打包环境配置 开发环境 测试环境 正式环境 --> |
6.2.3 pom.xml中设置资源文件配置
1 | <build> |
6.2.4 执行打包操作
不同环境使用命令进行指定
开发环境(默认为开发环境)
1
clean compile package -Dmaven.test.skip=true
测试环境
1
clean compile package -Ptest -Dmaven.test.skip=true
生产环境
1
clean compile package -Pprod -Dmaven.test.skip=true
6.2.5 查看打包文件
打包成功后,我们可以在target
文件夹中看到编译成功的项目,其中我们可以看到到资源文件的内容。
比如,在使用clean compile package -Pprod -Dmaven.test.skip=true
打包成生产环境后,我们可以看到资源文件内容如下:
6.2.6 原理
我们命令通过-P
指定参数,指定的参数会去找pom.xml
中的profile
标签的id
,如果有对应的则使用该profile
,而<directory>src/main/resources/${env}</directory>
中的${env}
则使用profile
标签中env
标签中的内容。而我们在resources
资源文件夹的目录名与env
标签中是一致的。
7、Maven仓库基本概念
当第一次运行Maven命令的时候, 你需要Internet链接, 因为它需要从网上下载一些文件。 那么它从哪里下载呢? 它是从Maven默认的远程库下载的。 这个远程仓库有Maven的核心插件和可供下载的jar文件。
对于Maven来说, 仓库只分为两类: 本地仓库和远程仓库。
当Maven根据坐标寻找构件的时候,它首先会查看本地仓库,如果本地仓库存在,则直接使用; 如果本地没有,Maven就会去远程仓库查找,发现需要的构件之后,下载到本地仓库再使用。 如果本地仓库和远程仓库都没有,Maven就会报错。
远程仓库分为三种: 中央仓库,私服, 其他公共库
中央仓库是在默认配置下,Maven下载jar包的地方。
私服是另一种特殊的远程仓库,为了节省带宽和时间,应该在局域网内架设一个私有的仓库服务器,用其代理所有外部的远程仓库。 内部的项目还能部署到私服上供其他项目使用。
一般来说,在Maven项目目录下,没有诸如lib/这样用来存放依赖文件的目录。 当Maven在执行编译或测试时,如果需要使用依赖文件,它总是基于坐标使用本地仓库的依赖文件。
默认情况下, 每个用户在自己的用户目录下都有一个路径名为.m2/repository/的仓库目录。 有时候,因为某些原因(比如c盘空间不足),需要修改本地仓库目录地址。
对于本地仓库存储路径的修改,可以通过maven 配置文件conf 目录下settings.xml来指定仓库路径。
1 | <!-- 设置到指定目录中,路径的斜杆不要写反 --> |
7.1 中央仓库
由于原始的本地仓库是空的,maven必须知道至少一个可用的远程仓库,才能执行maven命令的时候下载到需要的构件。中央仓库就是默认的远程仓库。
maven-model-builder-3.3.9.jar maven自动的 jar 中包含了一个 超级POM。定义了默认中央仓库的位置。
中央仓库包含了2000多个开源项目,接收每天1亿次以上的访问,由于访问量大,速度相较慢了。我们一般会更改远程仓库的路径。
7.2 私服
私服是一种特殊的远程仓库,它是架设在局域网内的仓库服务, 私服代理广域网上的远程仓库,供局域网内的maven用户使用。 当maven需要下载构件时, 它去私服当中找,如果私服没有, 则从外部远程仓库下载,并缓存在私服上, 再为maven提供。
此外,一些无法从外部仓库下载的构件也能从本地上传到私服提供局域网中其他人使用。
配置方式:在项目pom.xml 配置
1 | <repositories> |
公司内部应该建立私服:
节省自己的外网带宽
加速maven构建
部署第三方控件
提高稳定性
降低中央仓库的负荷
7.3 其他公共库
常用的阿里云仓库配置:阿里云maven仓库 https://developer.aliyun.com/mvn/guide
1 | <mirror> |
8、Maven构建多模块
以下案例以四个模块来创建项目。
- 模块
maven-parent
父模块(pom) - 模块
maven-dao
数据访问层(jar) - 模块
maven-service
项目的业务逻辑层(jar) - 模块
maven-controller
控制器层(war)
依赖关系:
8.1 创建空项目
选择File
->New
->Project
->Empty Project
8.2 创建maven-parent模块
不勾选Create from archetype
设置GroupId和ArtifactId、模块名称等
可以删除除了pom.xml的其它文件,仅保留pom.xml文件即可。
8.3 创建maven-dao模块
在maven-parent
目录点击右键选择New
->Module
输入模块名称
8.4 创建另外两个模块
同样的步骤创建另外两个模块,创建完成后目录结构如下:
8.5 配置模块之间的依赖关系
maven-parent
1 |
|
maven-dao
1 |
|
maven-service
1 |
|
maven-controller
1 |
|
8.6 添加方法和依赖
maven-dao
添加类
1 | package cn.yuencode; |
maven-service
添加类
1 | package cn.yuencode; |
maven-controller
添加类
1 | package cn.yuencode; |
maven-parent
父模块中依赖管理中添加servlet依赖
1 | <dependencyManagement> |
maven-controller
添加servlet依赖
不用指定版本,版本在父工程maven-parent
中统一管理。
1 | <dependency> |
8.7 启动项目
补充:
在
maven-controller
模块中配置打包方式为war
.pom.xml
1
<packaging>war</packaging>
在
maven-controller
模块中手动创建webapp
文件夹
8.7.1 方式一:在maven-controller中添加tomcat7插件
1 | <build> |
依次在maven-parent
、maven-dao
、maven-service
中执行mvn install
最后在maven-controller
中执行mvn tomcat7:run
8.7.2 方式二:在父工程maven-parent中添加tomcat7插件
此方式的好处是不需要依次在各个依赖模块中手动执行mvn install
命令。
直接在父工程maven-parent
中执行mvn tomcat7:run
即可。
访问地址:http://localhost:8088/maven-multi
运行结果:
完整代码:maven-multi.zip
9、Maven依赖的基本概念
9.1 依赖的基本配置
根元素project下的dependencies可以包含多个 dependency元素,以声明多个依赖。每个依赖都应该包含以下元素:
groupId
、artifactId
、version
:依赖的基本坐标,对于任何一个依赖来说,基本坐标是最重要的,Maven根据坐标才能找到需要的依赖。type
:依赖的类型,大部分情况下不需要声明。默认值为jar
scope
:依赖的范围。包含有compile
、test
、provided
、runtime
、system
compile
:编译依赖范围。如果没有指定,默认使用该范围。使用此依赖范围的Maven依赖,对于编译、测试、运行三种classpath有效。
test
:测试依赖范围。使用此依赖范围的Maven依赖,只对于测试classpath有效,在编译主代码或者运行项目时将无法使用该依赖。比如,Junit,它只有在编译测试代码以及运行测试的时候才需要被使用到。
provided
:已提供依赖范围。使用此依赖范围的Maven依赖,对于编译和测试classpath有效,但在运行时无效。例如
servlet-api
,编译和测试项目的时候需要该依赖,但是运行项目的时候,由于tomcat容器以及提供,就不需要Maven在重复引入。runtime
:运行时依赖范围。使用此依赖范围的Maven依赖,对于测试和运行classpath有效,但在编译主代码时无效。例如JDBC驱动,项目主代码的编译只需要JDK提供的JDBC接口,不需要实现类,只有在执行测试或者运行项目的时候才需要实现上述接口的具体JDBC驱动。
system
:系统依赖范围。该依赖范围与三种classpath的关系,和provided依赖范围完全一致。但是,使用system范围依赖时必须通过systemPath标签显式地指定依赖文件的路径。由于此类依赖不是通过Maven仓库解析的,而且往往与本机系统绑定,可能造成构建的不可移植,因此应该谨慎使用。
引入外部依赖
如果我们需要引入第三方库文件到项目,该怎么操作呢?
要添加依赖项,我们一般是先在 src 文件夹下添加 lib 文件夹,然后将你工程需要的 jar 文件复制到 lib 文件夹下。我们使用的是 ldapjdk.jar ,它是为 LDAP 操作的一个帮助库:
然后添加以下依赖到 pom.xml 文件中:
1 | <dependencies> |
optional
:标记依赖是否可选。exclusions
:用来排除传递依赖。
9.2 依赖范围
首先需要知道,Maven在编译项目主代码的时候需要使用一套classpath。比如:编译项目代码的时候需要用到spring-core
,该文件以依赖的方式被引入到classpath中。其次,Maven在执行测试的时候会使用另外一套classpath。如:junit。
最后在实际运行项目时,又会使用一套classpath,spring-core需要在该classpath中,而junit不需要。
那么依赖范围就是用来控制与这三种classpath(编译classpath、测试classpath、运行时classpath)的关系,Maven有以下几种依赖范围:
- compile:编译依赖范围。如果没有指定,就会默认使用该依赖范围。使用此依赖的Maven依赖,对于编译、测试、运行都有效。
- test:测试依赖范围。只有在测试的时候才有效。比如junit。
- provided:已提供依赖范围。使用此依赖范围的Maven依赖,对于编译和测试有效,但在运行时无效,例如servlet-api
- runtime:运行时依赖范围。使用此依赖范围的Maven依赖,对于测试和运行有效,但在编译代码时无效,例如JDBC驱动。
- system:系统依赖范围。与provided的作用域一致,一般不使用。
依赖范围 | 作用域 | 例子 |
---|---|---|
compile | 编译+测试+运行 | spring-core |
test | 测试 | junit |
provided | 编译+测试 | servlet-api |
runtime | 运行+测试 | jdbc驱动 |
system | 编译+测试 | 本地的依赖,maven仓库之外的依赖类库 |
可以发现5个依赖范围都包含测试作用域。provided为编译+测试,runtime为运行+测试,test为测试。其实可以理解,测试环境为本地环境其中类方法函数只能通过依赖提供,所以这个是必选的。
9.3 传递依赖
传递依赖机制,让我们在使用某个jar的时候就不用去考虑它依赖了什么,也不同担心引入多余的依赖。Maven会解析各个直接依赖
的pom,将那些必要的间接依赖,以传递性依赖的形式引入到当前项目中。
注意:传递依赖有可能产生冲突。
冲突场景:
1 | B依赖2.0版本的C |
这时候存在两个不同版本的C,冲突!需要我们手动进行解决,使用exclusion标签进行排除。
1 | <dependencies> |