一文带你了解Maven
项目的架构
目前项目存在的问题
Maven简介
Maven的简介
项目构建工具
Maven的四大特性
Maven的安装配置和目录结构
Maven的安装配置(基于Linux)
认识Maven的目录结构
Maven命令
常用命令
命令参数
IDEA部署Maven
Maven项目的创建
创建Java项目
创建web项目
Maven仓库的概念
中央仓库
私服
其他公共库
Maven环境下构建多模块项目
创建maven_parent项目
创建maven_dao项目(数据库层)
创建maven_service项目(业务逻辑层)
创建maven_controller项目
修改各个模块之间的配置
设置各个模块之间的依赖关系
Maven项目的打包操作
建立对应的目录结构
添加profile配置
设置资源文件配置
执行打包操作
Maven依赖的基本概念
依赖的基本配置
依赖范围
传递性依赖
往期内容回顾
Maven技术
项目的架构
目前项目存在的问题
一个项目就是一个工程 项目中所有需要的jar包必须手动“复制”、“粘贴”到WEB-INF/lib目录下 jar包需要别人替我们准备好,或到官网下载 一个jar包依赖其他jar包需要自己手动加入
Maven简介
Maven的简介
是apache下的一个成功的开源项目,Maven主要服务于基于java平台的项目构建、依赖管理和项目信息管理。
无论是小型的开源类库项目,还是大型的企业级应用,无论是传统的瀑布式开发还是流行的敏捷开发,Maven都能大显身手。
项目构建工具
Ant构建
最早的构建工具,其XML脚本编写格式让XML文件显得十分巨大。对工程构建过程中的控制做的很好,
Maven[Java]
项目对象模型,通过其描述信息来管理项目的构建,报告和文档的软件项目管理工具,它填补了Ant的缺点, Maven第一次支持了从网上下载的功能,仍然采用xml作为配置文件格式,Maven专注于依赖管理,使用Java 编写。
Gradle
属于结合以上两个的优点,它继承了Ant的灵活和Maven的生命周期管理,被谷歌作为安卓管理工具,最大的区别是 不用xml作为配置文件的格式,采用了DSL作为格式,脚本更加简洁。
Maven的四大特性
依赖管理系统
Maven为Java世界引入了一个新的依赖管理系统jar包管理,jar升级时修改配置文件即可,在Java世界中可以 用groupId、artifactId、version组成Coordination(坐标)唯一标识一个依赖
任何基于Maven构建的项目自身也必须定义这三项属性,生成的包可以是jar包,也可以是war包或者jar包,一个 典型的依赖引用如下所示:
<dependency>
<grouId>javax.servlet</grouId> com.baidu
<artifactId>javax.servlet-api</artifactId> ueditor echarts
<version>3.1.0</version>
</dependency>
坐标属性的理解
Maven坐标为各种组件引入了秩序,任何一个组件必须明确定义自己的坐标。
「groupId」
定义当前Maven项目隶属的实际项目-公司名称。(jar包所在仓库的路径)由于Maven中模块的概念,因此一个 实际项目往往会被划分成很多模块,比如spring是一个实际项目,其对应的Maven模块会有很多,如 spring-core、spring-webmvc等
「artifactId」
该元素定义实际项目中的一个Maven模块-项目名,推荐的做法是使用实际项目名作为artifactId的前缀,比如 spring-bean、spring-webmvc等
「version」
该元素定义Maven项目当前所处的版本,
多模块构建
项目复查时dao service controller层分离将一个项目分解为多个模块已经是很通用的一种方式。
在Maven中需要定义一个parent POM作为一组module的聚合POM,在该POM中可以使用<modules>
标签来定义
一组子模块,parent POM不会有什么实际构建产出。而parent POM中的build配置以及依赖都会自动继承给子
module。
一致的项目构建
Ant时代,大家创建Java项目目录时比较随意,然后通过Ant配置来指定哪些属于source,哪些属于 testsource等。而Maven在设计之初的理念就是Conversion over Configuration(约定大于配置), 其制定了一套项目目录结构作为标准的Java项目结构,解决不同ide带来的文件目录不一致问题。
一致的构建模型和插件机制
<plugin>
<groupId>org.mortbay.jetty</groupId>
<artifactId>maven-jetty-plugin</artifactId>
<version>6.1.25</version>
<configuration>
<scanIntervalScends>10</scanIntervalScends>
<contextPath>/test</contextPath>
</configuration>
</plugin>
Maven的安装配置和目录结构
Maven的安装配置(基于Linux)
通过终端查看自己是否已经安装了JDK的环境。(java -version命令查看)
下载最新的Maven项目,网址(http://maven.apache.org/download.html)
使用tar -zxvf apache-maven-x.x.x-bin.tar.gz -C /usr/local解压,解压后的文件夹名为:apache-maven-x.x.x
建立链接,方便升级:ln -s /usr/local/apache-maven-3.5.3/ maven
使用sudo vim /etc/profile编辑配置,按i进行插入,在末尾加上两行,内容如下:
export MAVEN_HOME=/usr/local/apache-maven-3.8.4
export PATH=$MAVEN_HOME/ bin :$PATH
esc退出编辑,输入:wq回车保存文件
source /etc/profile使环境参数生效
mvn –version查看Maven版本参数,看看是否配置正确。
为了每时每刻打开终端都可以及时查看maven的版本还需要配置一下bash.bashrc文件
export MAVEN_HOME=/usr/local/apache-maven-3.8.4
export PATH=$MAVEN_HOME/ bin :$PATH
vim /etc/bash.bashrc进入文件,进行编辑 添加步骤5的内容 完成之后按esc:wq退出vim编辑器 此时每次打开终端都可以查看maven的版本。
认识Maven的目录结构
目录 | 目的 |
---|---|
$(basedir) | 存放 pom.xml和所有的子目录 |
$(basedir)/src/main/java | 项目的java源代码 |
$(basedir)/src/main/resources | 项目的资源,比如property文件 |
$(basedir)/src/test/java | 项目的测试类,比如JUnit的代码 |
$(basedir)/src/test/resources | 测试使用的资源 |
手动创建一个maven项目
创建maven01项目,展示项目结构图
需要注意的是src与pom.xml文件处于同一级目录,main和test处于同一级目录,两个文件夹中都有java和resources子文件夹,命名固定。
填充pom.xml的文件内容,内容如下:
<?xml version="1.0" encoding="UTF-8"?>
<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
https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.xxx</groupId>
<artifactId>maven01</artifactId>
<version>0.01-SNAPSHOT</version>
<packaging>jar</packaging>
<name>maven01</name>
<url>http://maven.apache.org</url>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>3.8.1</version>
<scope>test</scope>
</dependency>
</dependencies>
</project>
POM结构如下:
<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>
<!-- 公司或者组织的唯一标志,并且配置时生成的路径也是由此生成, 如com.companyname.project-group,maven会将该项目打成的jar包放本地路径:/com/companyname/project-group -->
<groupId>com.companyname.project-group</groupId>
<!-- 项目的唯一ID,一个groupId下面可能多个项目,就是靠artifactId来区分的 -->
<artifactId>project</artifactId>
<!-- 版本号 -->
<version>1.0</version>
</project>
其中project,groupId,artifactId,version是一个POM文件所必需的几个要素。
大致的结构如下:
节点 | 描述 |
---|---|
project | 工程的根标签 |
modelversion | 模型版本需要设置为 4.0。 |
groupId | 这是工程组的标识。它在一个组织或者项目中通常是唯一的。例如,一个银行组织 com.companyname.project-group 拥有所有的和银行相关的项目。 |
artifactId | 这是工程的标识。它通常是工程的名称。例如,消费者银行。groupId 和 artifactId 一起定义了 artifact 在仓库中的位置。 |
version | 这是工程的版本号。在 artifact 的仓库中,它用来区分不同的版本。 |
创建主函数
package com.xxx.demo;
public class Hello{
public static void main(String[]args){
System.out.println("Hello Maven!");
}
}
编译运行Maven项目
修改默认仓库的位置
vim /usr/local/apache-maven-3.8.4/conf/settings.xml(使用vim编辑器打开xml文件)
找到localRepository标签,在其他目录下设置一个maven专用的依赖的下载仓库(我的是在/data/home/lambda/maven_Exercises_And Dependencies/Maven_Dependencies)
之后更换阿里源,提升maven的依赖下载速度(部署到idea中无效了)
在maven项目所在目录下打开终端,输入
mvn compile
编译项目编译完成后,运行mvn compile
Maven命令
作为开发利器maven,为我们提供了十分丰富的命令,了解maven命令行操作并熟练运用常见的maven命令十分有必要
maven命令的格式如下:
❝mvn [plugin-name] : [goal-name]
❞
命令代表的含义:执行plugin-name的goal-name目标
常用命令
命令 | 描述 |
---|---|
mvn -version | 显示版本信息 |
mvn clean | 清理项目生产的临时文件,一般是模块下的target目录 |
mvn compile | 编译源代码,一般编译模块下的src/main/java目录 |
mvn package | 项目打包工具,会在模块下的target目录生成jar或者war等文件 |
mvn test | 测试命令,或执行src/test/java下junit的测试用例 |
mvn install | 将打包的ajr/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文件所在的目录,否则必须通过指定参数来指定项目的目录。
❞
命令参数
其实maven中的很多命令都可以携带参数来执行
-D传入属性参数
例如:mvn package -Dmaven.test.skip=true
以-D开头,将maven.test.skip
的值设置为true,就是告诉maven打包的时候,跳过单元测试,同理,mvn deploy -Dmaven.test.skip=true
代表部署项目并跳过单元测试。
-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>
..........
<build>
<filters>
<filter>config/${env}.properties</filter>
</filters>
<resources>
<resource>
<directory>src/mian/resources</directory>
<filtering>true</filtering>
</resource>
</resources>
............
</build>
</profiles>
profiles
定义了各个环境的变量id,filters中定义了变量配置文件的地址,其中地址中的环境变量就是上面的profile中定义的值,resources中定义的是哪些目录下的文件会被配置文件中定义的变量替换。
通过maven可以实现按不同环境进行打包部署,例如:
mvn package -Pdev -Dmaven.test.skip=true
表示打包本地环境,并且跳过单元测试。
IDEA部署Maven
首先打开idea,打开settings
在搜索框搜索maven
右边找到home path和user settings进行修改
找到homePath目录,点击右侧的展开按钮,找到自己安装的maven目录位置,定位到bin目录的上一层目录
修改userSettings配置,首先先勾选override,打开下拉框,定位maven安装的目录,找到conf目录,选中settings.xml文件即可。
选择applay应用,即可
Maven项目的创建
创建Java项目
新建项目
新建项目
命名和定位位置
选择相应的maven版本(本机maven位于 /usr/local/apache-maven-3.8.4)
等待下载依赖并最终完成部署
编译打包项目
选择右上角的工具位置,选择编辑配置,找到maven
自定义编辑maven命令编译和打包
执行compile命令编译之后生成target目录
执行package打包命令之后生成jar包,位于target目录之下。
可以手动为src目录下的项目添加resource,并且右击选择相应的类型
创建web项目
创建项目
选择创建maven-webapp项目
之后同创建普通Java项目 建立完成的webapp项目
修改pom.xml文件
修改JDK的版本
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<maven.compiler.source>1.17</maven.compiler.source>
<maven.compiler.target>1.17</maven.compiler.target>
</properties>
修改Junit版本
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
<scope>test</scope>
</dependency>
删除掉所有的插件
<pluginManagement>
........
</pluginManagement>
<!--此标签及所有的标签内容全部删除-->
添加web部署插件
在build标签中添加plugins标签
添加Jetty插件
<plugin>
<groupId>org.mortbay.jetty</groupId>
<artifactId>maven-jetty-plugin</artifactId>
<version>6.1.25</version>
<configuration>
<!--热部署,每10s扫描一次-->
<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>8081</port>
<!--项目的站点名,即可以对外访问路径-->
<path>/test</path>
<!--指定字符编码-->
<uriEncoding>UTF-8</uriEncoding>
<server>tomcat7</server>
</configuration>
</plugin>
编译maven项目
添加相应的命令
添加jetty命令,以jetty形式运行index.jsp(应用jetty访问页面时需要注意xml文件中指定的端口以及站点名)
添加tomcat命令
Maven仓库的概念
当第一次运行maven项目的时候,需要Internet连接,它需要在网上下载一些文件,即是从Maven默认的远程库下载的,这个远程库有Maven的核心插件和可供下载的jar包
对于Maven来说,仓库只分为两类:「本地仓库和远程仓库」
当Maven根据坐标寻找构件的时候,它首先会查看本地仓库,如果本地仓库存在,则直接使用,如果本地仓库没有,则会去远程仓库查找,发现需要的构件之后,下载到本地仓库之后再使用。如果本地仓库和远程仓库都没有,maven就会报错。
远程仓库又分为三种:「中央仓库,私服,其他的公共库」
中央仓库是默认配置下载,即Maven下载jar包的地方。 私服是一种特殊的远程仓库,为了节省带宽和时间,应该在局域网内架设一个私有的仓库服务器,用其代理所有的外部远程仓库,内部的项目还能部署到私服上供其他项目使用。
一般来说,在Maven项目的目录下,没有诸如lib/这样的用来存放其依赖文件的目录,当Maven在执行编译或者测试时,如果需要使用依赖文件,它总是基于坐标使用本地仓库的依赖文件。
默认情况下,每个用户在自己的用户目录下都有一个名为.m2/repository的仓库目录,有时候因为某些原因,需要修改本地仓库目录地址。
对于仓库路径的修改,可以通过maven配置conf目录下的settings.xml来指定仓库的路径。
中央仓库
由于原始的本地仓库是空的,maven必须知道至少一个可用的远程仓库,才能执行maven命令的时候下载到需要的构件,中央仓库就是这样一个默认的远程仓库
maven-model-builder-3.3.9.jar maven自动的jar包中包含一个超级POM。定义了默认中央仓库的位置,中央仓库包含了2000多个开源项目,接受每天1亿次以上的访问。
私服
私服是一种特殊的远程仓库,它是架设在局域网中的仓库服务,私服代理广域网上的远程仓库,供局域网内的maven用户使用,当maven需要下载构件时,它会去私服上寻找,如果私服没有,则从外部远程仓库寻找下载,并缓存在私服上,再为maven提供。
此外,一些无法从外部仓库上下载的构件也能从本地上传到私服提供局域网中其他人使用,
配置pom.xml来创建私服
<repositories>
<repository>
<snapshots>
<enabled>true</enabled>
</snapshots>
<id>public</id>
<name>public repository</name>
<url>http://xxxxxx/content/groups/public/</url>
</repository>
<repository>
<id>getui-nexus</id>
<url>http://mvn.gt.igexin.com/nexus/content/repositories/releases/</url>
</repository>
</repositories>
公司内部应该建立私服
节省自己外网的带宽 加速maven构建 部署第三方控件 提高稳定性 降低中央仓库的负荷
其他公共库
常用的阿里云仓库配置
<mirror>
<id>alimaven</id>
<mirrorOf>central</mirrorOf>
<name>aliyun maven</name>
<url>http://maven.aliyun.com/nexus/content/repositories/central</url>
</mirror>
Maven环境下构建多模块项目
使用Maven提供的多模块构建特性完成maven环境下多个模块的项目的管理与构建
❝这里以四个模块为例来搭建项目,以达到通俗易懂的的初衷。
模块maven_parent ———基模块,就是常说的parent(pom)
模块maven_dao——数据库的访问层,例如jdbc操作(jar)
模块maven_service——项目的业务层逻辑(jar)
模块maven_controller——用来接收请求,响应数据(war)
❞
创建maven_parent项目
新建新的project,选中相应的JDK版本,(注意无需添加任何的模板文件)填写相应的groupId和artifactId
之后点击finish,开始下载依赖
创建maven_dao项目(数据库层)
创建完父模块之后创建子模块,首先创建普通java子模块(需要注意选中相应的JDK版本,和quickstart启动文件)
设置和修改相应的参数(artifactId)
等待自动创建dao项目即可
创建maven_service项目(业务逻辑层)
创建过程同maven_dao的第一个过程 修改相应的artifactId(maven_service) 等待下载依赖完成
创建maven_controller项目
选择相应的JDK并选择webapp模板文件
修改相应的参数
等待下载依赖,完成项目创建
修改各个模块之间的配置
修改相应的JDK版本(将1.7->改为所使用的JDK版本) 修改对应的junit单元测试版本(如改为4.12) 删除多余配置(pluginManagement标签之内的所有无用配置)
设置各个模块之间的依赖关系
设置maven_dao模块
首先在com.xxxx下新建一个包,命名为dao
在dao包下新建一个类,命名为UserDao,并且定义一个方法(以便后续其他层调用)
设置mavne_service模块
首先在service模块中找到com.xxx,新建一个包命名为service
其次,需要在maven_service的pom.xml文件中添加maven_dao的项目依赖。
在service包中创建一个UserService类,并创建一个静态方法testService,并在方法内调用maven_dao模块中的testDao方法
设置maven_controller模块
由于controller模块需要引用service模块中的方法,因此需要首先引入service模块的依赖,并且由于是web项目,需要引入servlet依赖。
在maven_controller模块中创建java目录,并在该目录下创建包com.xxx.controller,并在该包下创建UserController类,实现相应的方法。
添加tomcat插件
<plugin>
<groupId>org.apache.tomcat.maven</groupId>
<artifactId>tomcat7-maven-plugin</artifactId>
<version>2.1</version>
<configuration>
<!--启动端口,默认8080-->
<port>8081</port>
<!--项目的站点名,即可以对外访问路径-->
<path>/test</path>
<!--指定字符编码-->
<uriEncoding>UTF-8</uriEncoding>
<server>tomcat7</server>
</configuration>
</plugin>
启动项目
创建tomcat的启动命令
添加一些其他项目的install命令(打包供其他模块使用)
分别执行maven_parent maven_dao,maven_service,maven_controller的打包命令
最后都显示打包成功
最后运行tomcat命令去网页上访问相应的内容,同时控制台打印方法中的内容。运行成功。
出现的问题
出现无效的发行版
解决方案:
首先选择file->settings->builder那一栏->选择javacompiler,设置相应的参数
选择file->project structure->project,之后设置相应的参数,之后选择modules,选择相应的JDK版本
maven项目打包时出现 Error injecting: org.apache.maven.plugin.war.WarMojo
解决方案:
为项目添加相应的依赖
Maven项目的打包操作
对于企业级项目,无论是进行本地测试,还是测试环境以及最终的项目上线,都会涉及项目的打包操作。对于每个环境下的项目打包,对应的项目所需要的配置资源都会有所区别,实现打包的方式有很多种,可以通过ant或者通过idea自带的打包功能的实现项目打包。但当项目很大并且需要的外界配置很多时,此时打包的配置就可能会异常复杂,对于maven项目,我们可以通过pom.xml配置的方式来实现打包时的环境选择,相比较其他形式打包工具,通过maven只需要通过简单的配置,就可以轻松完成不同环境下项目的整体打包。
比如下面的项目,项目中配置了不同环境下项目所需要的配置文件,这时需要完成不同环境下的打包操作,此时通过修改pom.xml,如下:
建立对应的目录结构
使用idea创建项目,可能导致目录结构缺失,需要手动添加相应的目录。
创建一个maven的web项目(删除相应的配置)
在项目中添加java的源文件夹和资源目录resources
在resources目录下创建三个目录,分别对应生产环境,测试环境和产品正式环境
分别为新建的三个目录添加相应的配置文件
添加profile配置
<!--打包环境配置,开发环境,测试环境,正式环境-->
<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>
将上述的配置信息放置到pom.xml文件中,进行相应的配置,一般把默认的打包环境放到测试或者开发环境。
设置资源文件配置
<!--对于项目资源文件的配置放在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>
执行打包操作
常规的打包操作,即直接执行package命令,生成war包
clean compile package -Pdev -Dmaven.test.skip=true
命令解读:clean:表示清除之前的打包文件,compile表示编译,package表示打包,-Pxxx表示指定哪里的配置文件(profile),这里的位置即是pom.xml文件中的id标签的值,-D表示传入参数,maven.test.skip表示跳过测试文件,设置为ture
指定dev环境的打包
指定test环境的打包
指定product环境的打包
最终运行三者的命令,都显示打包成功
Maven依赖的基本概念
依赖的基本配置
根元素project下的dependencies可以包含多个dependence元素,以声明多个依赖,每个依赖都应该包含以下元素
groupId,artifactId,version:依赖的基本坐标,对于任何一个依赖来说,基本坐标是最重要的,Maven根据坐标才能找到相应的依赖。 Type:依赖的类型,大部分情况下不需要声明,默认值为jar 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:系统依赖范围,该依赖与三种classpath的关系,和provided的完全一致,但是system范围依赖时必须通过systemPath元素显式指定依赖文件的路径,由于此类依赖不是通过maven仓库解析,而且往往与本机系统锁定,可能造成构建的不可移植,因此需要谨慎使用。
依赖范围
Maven在编译项目主代码的时候需要使用一套classpath,比如:编译项目代码的时候需要用到spring-core,该文件以依赖的方式被引入到classpath中,其次,Maven在执行测试的时候又会使用另外一套classpath,比如junit。最后在实际的项目运行中,又会使用一套classpath,spring-core就需要在classpath中,而junit不需要。
依赖范围就是用来控制依赖与这三种classpath(编译classpath,测试classpath,运行时classpath)的关系,对应的依赖范围同上的scope。
传递性依赖
传递依赖机制,让我们在使用某个jar的时候不需要考虑它依赖了什么,也不用担心引入多余的依赖,Maven会解析各个直接依赖的pom,将那些必要的间接依赖,以传递性依赖的形式引入到当前项目中。
注意:传递依赖可能产生冲突!
冲突场景
❝A—>B—->C(2.0)
A—>E—–>C(1.0)
❞
A间接依赖了2.0版本的C和1.0版本的C,就产生了冲突。
如果A下同时存在两个不同版本的C,则产生了冲突(选取同时适合A,B的版本)
<dependencies>
<dependency>
<groupId>A</groupId>
<artifactId>A</artifactId>
<version>xxxx</version>
<!--排除依赖冲突-->
<exclusions>
<exclusion>
<groupId>C</groupId>
<artifactId>C</artifactId>
</exclusion>
</exclusions>
</dependency>
</dependencies>