Maven基础知识!

基本信息

标 签 作 用
groupId 通常为组织或公司域名反写
artifactId 项目的名称
version 项目的版本信息
name 项目的简称
description 项目的简要描述

生命周期

clean

  • 清除当前工程编译后生成的文件(即删除target整个目录)

validate

  • 对工程进行基础验证,如工程结构、pom、资源文件等是否正确

compile

  • src/main/java目录下的源码进行编译(会生成target目录)

test

  • 编译并执行src/test/java/目录下的所有测试用例

package

  • 将当前项目打包,普通项目打jar包,webapp项目打war

verify

  • 验证工程所有代码、配置进行是否正确,如类中代码的语法检测等

install

  • 将当前工程打包,然后安装到本地仓库,别人可通过GAV导入

site

  • 生成项目的概述、源码测试覆盖率、开发者列表等站点文档(需要额外配置)

deploy

  • 将当前工程对应的包,上传到远程仓库,提供给他人使用(私服会用)

依赖范围

项目引入的所有依赖,如果不显式指定依赖范围,默认是compile,意味着所有环境下都生效。

一般的依赖包无需更改,只有某些特殊的依赖,才需要手动配置一下,如:

  • JUnit、spring-test这类包,只在测试环境使用,所以配成test
  • Tomcat内置servlet-api包,为了避免在运行环境冲突,应该配成provided
依赖范围 编译环境 测试环境 运行环境
compile 生效 生效 生效
provided 生效 生效 不生效
system 生效 生效 不生效
runtime 不生效 生效 生效
test 不生效 生效 不生效

间接依赖

如果Dependency-A 引用了 Dependency-B ,而 Dependency-B 又依赖于 Dependency-C

  • 只需要引入Dependency-B即可,Maven会自动将子模块所依赖的包导入。

依赖顺序:

如工程中引入 Dependency-ADependency-B 两个依赖,二者又分别引用了不同版本的 Dependency-C

但最终编译时同一个依赖即便是不同的版本也只会选择一份。

计算规则:

  • Dependency-A 定义在 Dependency-B 之前,则最终将导入 Dependency-A 中的 Dependency-C 版本。

依赖调解

当一个间接依赖存在多条引入路径时,为避免依赖重复Maven会通过依赖调解来确定该间接依赖的引入路径。

依赖调解遵循以下原则,优先使用第一原则,当第一原则无法解决时,则通过第二原则解决。

  • 第一原则: 路径最短者优先。
  • 第二原则: 第一声明者优先。

可选依赖

当某个间接依赖是可选依赖时,无论依赖范围是什么,其都不会因为传递性依赖机制而被引入。

  • 只有显式地配置项目中某依赖的option元素为true时,该依赖才是可选依赖。

排除依赖

在引用多个模块时可能会发生版本兼容冲突问题,通过 exclusions 标签即可实现依赖排除。

1
2
3
4
5
6
7
8
9
10
11
<dependency>
<groupId>com.apple</groupId>
<artifactId>B</artifactId>
<version>2.3</version>
<exclusions>
<exclusion>
<groupId>com.google</groupId>
<artifactId>C</artifactId>
</exclusion>
</exclusions>
</dependency>

变量配置

当项目中引入了大量依赖,为了方便管理通常将引入依赖的版本通过变量进行统一配置,从而实现更直观的依赖管理。

通过 properties 标签即可自定义变量配置,然后使用 ${} 引用变量。

1
2
3
4
5
6
7
8
9
10
11
12
<properties>
<mysql.version>8.0.30</mysql.version>
</properties>

<dependencies>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<!-- 使用 "${}" 引用上述自定义变量 -->
<version>${mysql.version}</version>
</dependency>
</dependencies>

模块配置

模块继承:

通过 parent 即可标记当前模块的父模块,且子模块将会继承父模块中的所有依赖配置。

  • 子模块若没有指定的 groupIdversion 默认继承父模块中的配置。

其中 relativePath 用于指定父模块的 POM 文件目录,省略时默认值为 ../pom.xml

即当前目录的上一级中,若仍未找到则会在本地仓库中寻找。

1
2
3
4
5
6
7
8
9
<!-- module-1 pom.xml -->
<parent>
<groupId>xyz.ibudai</groupId>
<artifactId>maven-demo</artifactId>
<version>1.0-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>

<artifactId>module-1</artifactId>

依赖管理

将项目依赖统一定义在父模块的 dependencyManagement 标签中。

子模块只需继承父模块并在 dependencies 引入所需的依赖,便可自动读取父模块 dependencyManagement 所指定的版本。

dependencyManagement 既不会在当前模块引入依赖,也不会给其子模块引入依赖,但其可以被继承的。

只有在子模块下同样声明了该依赖,才会引入到模块中。

子模块中只需在依赖中引入 groupIdartifactId 即可,也可以指定版本则会进行覆盖。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
<dependencyManagement>
<dependencies>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>8.0.30</version>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.13.2</version>
</dependency>
</dependencies>
</dependencyManagement>

构建配置

版本指定:

<plugin> 标签内可指定工程打包编译时使用的 JDK 版本,可根据服务器环境手动修改版本。

1
2
3
4
5
6
7
8
9
10
11
12
<plugins>
<plugin>
<!-- 编译时使用 JDK 版本 -->
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.1</version>
<configuration>
<source>8</source>
<target>8</target>
</configuration>
</plugin>
</plugins>

主类配置

在打包时可能出现无法识别工程主类的问题,导致编译后的文件无法正常运行,此时则可以在 pom 文件中手动设置工程的主类。

  • 其中 <mainClass> 中配置的为项目主类的完成限定名。
1
2
3
4
5
6
7
8
9
10
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<configuration>
<mainClass>xyz.ibudai.TestWebApplication</mainClass>
<layout>JAR</layout>
</configuration>
</plugin>
</plugins>