Maven三大功能:依赖管理、项目构建、项目知识管理;需要上项目最重要的功能是首先能用Maven正确添加需要的JAR(依赖管理)
classifier:用来帮助定义构建输出的一些附属构建;不能直接定义项目的classifier,因附属构建不是项目直接默认生成的,而是由附加的插件帮助生成。
pom.xml基础配置:
<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 指定POM的版本,对于maven2及maven3来说,它只能是4.0.0 -->
<modelVersion>4.0.0</modelVersion>
<!-- groupId、artifactId、version、package和classifier可唯一确定Maven坐标; -->
<!-- groupId 项目组的ID,一般是com.公司组织名.项目名 -->
<groupId>com.chensan.app</groupId>
<!-- artifactId 该项目在项目组中的ID -->
<artifactId>app-sample</artifactId>
<!-- version 是项目的版本号,用于维护项目的升级和发布;SNAPSHOT意为快照,说明该项目还处于开发中,是不稳定的版本 -->
<version>0.0.1-SNAPSHOT</version>
<!-- Maven项目的打包方式, 有jar、war、pom等方式, 默认打包方式jar -->
<packaging>jar</packaging>
<!-- name 一般没有实际的用处, 只是用于标识该项目, Maven产生的文档用 -->
<name>app-sample</name>
<!-- 项目主页的URL, Maven产生的文档用 -->
<url>http://maven.apache.org</url>
<!-- 依赖管理在下面依次会引入 -->
</project>
1. 依赖的配置
groupId,artifactId和version:依赖的基本坐标,对于任何一个依赖来说,基本坐标是最重要的,Maven根据坐标才能找到需要的依赖。 根元素project下的dependencies可以包含一个或者多个dependency元素,以声明一个或者多个依赖。
scope: 依赖的范围,下面会进行详解
optional: 标记依赖是否可选
exclusions: 用来排除传递性依赖,下面会进行详解
2. 依赖范围
Maven在编译、测试、运行时分别要使用一套classpath,依赖范围就是用来控制依赖与依赖与这三种classpath(编译classpath、测试classpath、运行classpath)的关系。
Maven有四种依赖范围:
1) compile:编译依赖范围,如果没有指定依赖范围,则默认使用此依赖范围; 对于编译、测试、运行三种 classpath 都有效,即在编译、测试和运行的时候都使用该依赖;
2) test:测试依赖范围; 在编译主代码和运行项目时无法使用此类依赖。典型的是JUnit,它只用于编译测试代码和运行测试代码的时候才需要;
3) provided:已提供依赖范围,对于编译和测试classpath有效, 但在运行时无效;
4) runtime:运行时依赖范围,对于测试和运行classpath有效,但是在编译主代码时无效;
5) system:系统依赖范围, 该依赖与三种classpath的关系和provided依赖范围完全一致。但是使用system范围的依赖时必须通过systemPath元素显示地指定依赖文件的路径; 由于此类依赖不是通过Maven仓库解析的, 而且往往与本机系统绑定, 可能造成构建的不可 移植所以可能会造成建构的不可移植,须谨慎使用。
3.传递性依赖
B->C(compile) 第二直接依赖关系: b依赖c
<dependency>
<groupId>com.B</groupId>
<artifactId>B</artifactId>
<version>1.0</version>
</dependency>
则会自动导入c包
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
<scope>test</scope>
</dependency>
Ctrl+鼠标左键点击,进入junit:4.12.pom中,里面有引用hamcrest-core-1.3.jar,此为第二直接关系:
<dependencies>
<dependency>
<groupId>org.hamcrest</groupId>
<artifactId>hamcrest-core</artifactId>
<version>1.3</version>
</dependency>
</dependencies>
于是项目中也会传递依赖引入hamcrest-core-1.3.jar
4.依赖冲突调解
A->B->C->X(1.0)
A->D->X(2.0)
由于只能引入一个版本的包,此时Maven按照最短路径选择导入x(2.0)
Maven依赖调解的第二原则:路径长度一致,第一声明者优先。
多个声明的路径一样长,则只解析最前面的那个声明。
A->B->X(1.0)
A->D->X(2.0)
路径长度一致,优先选择第一个,此时导入x(1.0)
5.排除依赖
A->B->C(1.0)
此时在A项目中,不想使用C(1.0),而使用C(2.0)
则需要使用exclusion排除B对C(1.0)的依赖。并在A中引入C(2.0)。
或者说在A中不想引用C的jar包。
pom.xml中配置
<!--排除B对C的依赖-->
<dependency>
<groupId>B</groupId>
<artifactId>B</artifactId>
<version>0.1</version>
<exclusions>
<exclusion>
<groupId>C</groupId>
<artifactId>C</artifactId><!--无需指定要排除项目的版本号-->
</exclusion>
</exclusions>
</dependency>
<!---在A中引入C(2.0)-->
<dependency>
<groupId>C</groupId>
<artifactId>C</artifactId>
<version>2.0</version>
</dependency>
实例:还是以引入junit-4.12.jar为例,但是不希望引入hamcrest-core-1.3.jar,而是换为hamcrest-core-1.2.jar(没谁正常适配版本不用,去换低版本的,只是测试下效果,别喷啊);
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
<scope>runtime</scope>
<exclusions>
<exclusion>
<groupId>org.hamcrest</groupId>
<artifactId>hamcrest-core</artifactId><!--无需指定要排除项目的版本号version-->
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.hamcrest</groupId>
<artifactId>hamcrest-core</artifactId>
<version>1.2</version>
</dependency>
exclusion排除了对hamcrest-core-1.3.jar的传递依赖,则项目不会导入hamcrest-core的jar包;后面dependency可引用该jar包其它版本;
已成功将hamcrest-core-1.3.jar换成1.2版本;
6.可选依赖
<project>
...
<dependencies>
<dependency>
<groupId>sample.ProjectA</groupId>
<artifactId>Project-A</artifactId>
<version>1.0</version>
<optional>true</optional>
</dependency>
</dependencies>
</project>
7.归类依赖
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-core</artifactId>
<version>4.3.4.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-beans</artifactId>
<version>4.3.4.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>4.3.4.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-orm</artifactId>
<version>4.3.4.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-aop</artifactId>
<version>4.3.4.RELEASE</version>
</dependency>
如上 引入spring的一系列jar包,然而后期如果修改jar包版本则管理起来不方便,这里就可以用到归类依赖。
如博文最上面Spring的JAR为同一版本,为方便后期修改和管理,增加了个自定义的property,以后修改只需要修改property里的版本号即可;
<project>
...
<properties>
<springframework.version>4.3.4.RELEASE</springframework.version>
</properties>
<!-- 它们自动从项目定义的仓库(本地仓库、中央仓库、远程仓库)中下载项目配置的依赖jar包。-->
<dependencies>
...
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-core</artifactId>
<version>${springframework.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-beans</artifactId>
<version>${springframework.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>${springframework.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-orm</artifactId>
<version>${springframework.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-aop</artifactId>
<version>${springframework.version}</version>
</dependency>
</dependencies>
</project>