Maven
简介
Maven 是一个项目管理工具,可以对 Java 项目进行构建、依赖管理。
作用
- 解决导入java类依赖的jar,以pom.xml文件中dependency属性管理依赖的jar包
- 自动解决重复和冲突问题
- 作为一个开放的架构,提供了公共接口,方便同第三方插件集成。程序员可以将自己需要的插件,动态地集成到 Maven,从而扩展新的管理功能。
- 可以统一每个项目的构建过程,实现不同项目的兼容性管理。
网站
官网下载地址:
http://maven.apache.org/download.cgi
maven仓库:
https://mvnrepository.com/
安装及配置
安装
解压即可
配置
- 环境变量
变量名 | MAVEN_HOME | 变量值 | D:\maven\apache-maven-3.6.3 |
---|---|---|---|
变量名 | path | 变量值 | %MAVEN_HOME%\bin |
- 验证
cmd
-> mvn -v
-
配置本地仓库
- 新建
repository
文件夹,作为本地仓库 apache-maven-3.6.3
->conf
->settings.xml
将默认地址改成
- 新建
<localRepository>D:\maven\repository</localRepository>
- 配置阿里云镜像
mirrorOf
的值为 central,表示该配置为中央仓库的镜像。任何对于中央仓库的请求都会转至该镜像
<mirrors>
<mirror>
<id>alimaven</id> <!-- 镜像唯一标识符 -->
<name>aliyun maven</name> <!-- 镜像名称 -->
<url>http://maven.aliyun.com/nexus/content/groups/public/</url> <!-- 镜像url -->
<mirrorOf>central</mirrorOf> <!--被镜像的服务器的id。例如,如果我们要设置了一个Maven中央仓库(http://repo.maven.apache.org/maven2/)的镜像,就需要将该元素设置成central。这必须和中央仓库的id central完全一致。-->
</mirror>
</mirrors>
- 配置私服
(1)mirrorOf
的值为星号(*),表示该配置是所有maven仓库的镜像。任何对于远程仓库的请求都会被转至私服(http://192.168.1.100/maven2/)
(2)如果该镜像仓库需要认证,则配置一个 id 为 internal-repository 的server
即可
<mirrors>
<mirror>
<id>internal-repository</id>
<name>Internal Repository Manager</name>
<url>http://192.168.1.100/maven2</url>
<mirrorOf>*</mirrorOf>
</mirror>
</mirrors>
<servers>
<server>
<id>internal-repository</id> <!-- 镜像的id -->
<username>user</username>
<password>pwd</password>
</server>
</servers>
基本命令
命令 | 说明 |
---|---|
mvn -v | 查询maven版本 |
mvn clean | 清空以前编译安装过的历史结果,一般是模块下的target目录 |
mvn compile | 将java源文件编译成class文件 |
mvn test | 执行test目录下的测试用例 |
mvn package | 将项目打成jar包 |
mvn install | 将当前代码打成 jar 包,安装到 Maven 的本地管理目录下,其他 Maven 工程只要指定坐标就可以使用 |
pom.xml
<?xml version="1.0" encoding="UTF-8"?>
<!-- 最外层是project标签 -->
<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> <!-- 指定当前maven模型版本号,对于maven2和maven3,只能是4.0.0 -->
<!-- 基本配置 -->
<groupId>com.airboom</groupId> <!-- 公司或组织ID,用于maven定位 -->
<artifactId>demo</artifactId> <!-- 项目ID -->
<version>1.0-SNAPSHOT</version> <!-- 版本号,SNAPSHOT意为快照,说明该项目还在开发中 -->
<packaging>war</packaging> <!-- 打包格式,可以为jar、war、rar、ear、pom等,默认是jar -->
<!-- 依赖配置 -->
<dependencies>
<dependency>
<groupId>junit</groupId> <!-- 依赖的组织ID -->
<artifactId>junit</artifactId> <!-- 依赖的项目ID -->
<version>4.0</version> <!-- 依赖的版本 -->
<scope>test</scope> <!-- 依赖适用范围,compile,provided,runtime,test,system,exclusions,详见依赖项适用范围 -->
<optional>true</optional> <!-- 可选依赖,默认为false,详细见可选依赖和依赖排除 -->
<exclusions> <!-- 排除依赖,详细见可选依赖和依赖排除 -->
<exclusion>
<groupId>xxx</groupId>
<artifactId>xxx</artifactId>
</exclusion>
</exclusions>
</dependency>
</dependencies>
<parent> <!-- 父项目依赖 -->
<groupId>com.example</groupId>
<artifactId>demo</artifactId>
<version>1.0-SNAPSHOT</version>
<relativePath>../ParentProject/pom.xml</relativePath> <!-- maven首先在当前项目中找父项目的pom,然后在文件系统的这个位置(relativePath)查找,然后在本地仓库查找,再在远程仓库找。 -->
</parent>
<modules> <!-- 多模块聚合 -->
<module>com-B</module>
<module>com-C</module>
<modules/>
<properties> <!-- 定义pom文件中的常量,在pom文件的任何地方,都可以通过${rocketmq.version}来引用该值 -->
<rocketmq.version>3.2.6</rocketmq.version>
</properties>
<dependencyManagement>...</dependencyManagement> <!-- 见dependencyManagement -->
<!-- 构建配置 -->
<build>...</build>
<reporting>...</reporting>
<!-- 以下信息均可省略 -->
<!-- 项目信息 -->
<name>...</name> <!-- 声明一个对用户更加友好的项目名称,一般用于maven生成文档 -->
<description>...</description> <!-- 项目的详细描述信息,一般用于maven生成文档 -->
<url>...</url> <!-- 项目主页url,一般用于maven生成文档 -->
<inceptionYear>...</inceptionYear> <!-- 项目开始年份 -->
<licenses>...</licenses> <!-- 当前项目所有的许可文件 -->
<organization>...</organization> <!-- 组织相关信息 -->
<developers>...</developers> <!-- 项目开发人员列表 -->
<contributors>...</contributors> <!-- 项目贡献者列表 -->
<!-- 环境设置 -->
<issueManagement>...</issueManagement>
<ciManagement>...</ciManagement>
<mailingLists>...</mailingLists>
<scm>...</scm>
<prerequisites>...</prerequisites>
<repositories>...</repositories>
<pluginRepositories>...</pluginRepositories>
<distributionManagement>...</distributionManagement>
<profiles>...</profiles>
</project>
依赖项适用范围
- compile:缺省值,编译范围,适用于所有阶段,会随项目一起发布
- provided:已提供范围,由JDK、容器或使用者提供这个依赖
- runtime:运行时范围,适用于运行和测试阶段,但编译时不需要;如JDBC驱动,编译时只需要JDBC API相关的jar,在运行时才需要JDBC驱动实现
- test:测试范围,只在测试时使用,在一般的编译和运行时都不需要,只有在测试编译和测试运行阶段适用
- system:系统范围,类似provided,需要显式提供包含依赖的jar,maven不会在repository中查找它(不推荐使用)
- optional:当项目自身被依赖时,标注依赖是否传递,用于连续依赖时使用
可选依赖和依赖排除
maven的依赖关系具有传递性,如:A->B,B->C。但有时候 A 可能不是必须依赖 C,因此在项目 A 中排除对 C 的依赖。在maven依赖管理中,有2中方式对依赖进行管理:可选依赖可选依赖(Optional Dependencies)和依赖排除(Dependency Exclusions)
可选依赖
当项目 A 依赖项目 B 时,可能用到项目 B 很少一部分功能,此时可以在 A 中配置对 B 的可选依赖。
<dependencies>
<dependency>
<groupId>com.B</groupId>
<artifactId>B</artifactId>
<version>1.0</version>
<scope>compile</scope>
<optional>true</optional>
</dependency>
</dependencies>
假设以上配置是项目 A 的,即 A -> B,在编译 A 时,可以正常通过;如果新的项目 C 依赖 A ,此时 C 就不会依赖项目 B 了,如果项目 C 需要用到项目 B 的功能,就需要在 pom.xml 中重新配置对项目 B 的依赖。
依赖排除
当项目 A 依赖项目 B,而项目 B 同时依赖项目 C,如果项目 A 中不想引用项目 C,在配置项目 B 的依赖时,可以排除对 C 的依赖,假设配置的是 A 的 pom.xml:
<dependencies>
<dependency>
<groupId>com.B</groupId>
<artifactId>B</artifactId>
<version>1.0</version>
<scope>compile</scope>
<exclusions>
<exclusion>
<groupId>com.C</groupId>
<artifactId>C</artifactId>
</exclusion>
</exclusions>
</dependency>
</dependencies>
对于多重依赖,配置也很简单,A -> B -> C -> D(要排除) -> E,A 对于 D 相当于有多重依赖,在排除对 D 的依赖时,只需在配置 B 的依赖中进行即可,假设配置的是 A 的 pom.xml:
<dependencies>
<dependency>
<groupId>com.B</groupId>
<artifactId>B</artifactId>
<version>1.0</version>
<exclusions>
<exclusion>
<groupId>com.D</groupId>
<artifactId>D</artifactId>
</exclusion>
</exclusions>
</dependency>
</dependencies>
dependencyManagement
如果一个项目模块很多,dependencyManagement可以用来管理子项目的公共依赖。为了项目的正确运行,必须让所有的子项目使用依赖项统一版本,通过该元素来管理jar包的版本,让子项目中引用一个依赖而不用显示的列出版本号。在父项目中用dependencyManagement声明依赖的版本:
<!-- 父项目中定义:-->
<dependencyManagement>
<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
<scope>test</scope>
</dependency>
</dependencies>
</dependencyManagement>
<!-- 子项目先通过parent继承之后,就可以引入使用 -->
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
</dependency>
需要注意的是:
dependencyManagement里只是声明依赖,并不实现引入。如果不在子项目中声明依赖,不会从父项目中继承;只有在子项目中写了该依赖项,并且没有指定具体版本,才会从父项目中继承该项,并且version和scope都读取自父pom。如果子项目中指定了版本号,那么会使用子项目中指定的jar版本。