Getting started with Maven
Maven
为什么使用 Maven ?
当如果我们的项目依赖第三方的jar包,例如 JDBC 驱动: mysql-connector-java ,我们需要手动下载,并配置加载到工程中。 需要测试时,我们需要 JUnit 包,又要重复上述过程,新建了一个工程,又需要重新配置。
- 有没有一个工具可以帮我们自动下载并导入包呢? -> Maven
Maven 简介
Maven 是一个标准化的Java项目管理和构建工具。解决了依赖管理问题。
- 提供了一套标准化的项目结构;
- 提供了一套标准化的构建流程(编译,测试,打包,发布……);
- 提供了一套依赖管理机制。
标准目录结构
一般的工程包括这四部分
- 核心代码部分
- 配置文件部分
- 测试代码部分
- 测试配置文件
maven 标准目录结构
- 一个使用Maven管理的普通的Java项目,它的目录结构默认如下:
a-maven-project
├── pom.xml
├── src
│ ├── main
│ │ ├── java
│ │ └── resources
│ └── test
│ ├── java
│ └── resources
└── target
目录 | 作用 |
---|---|
/src/main/java | 项目的java源代码 |
/src/main/resources | 项目的资源,配置文件,比如说property文件,springmvc.xml |
/src/test/java | 项目的测试类,比如说Junit代码 |
/src/test/resources | 测试用的资源 |
/src/main/webapp | Web应用文件目录,web项目的信息 |
/target | 打包输出目录 |
/target/classes | 编译输出目录 |
/target/test-classes | 测试编译输出目录 |
Maven POM
POM ( Project Object Model,项目对象模型 ) 是 Maven 工程的基本工作单元,是一个XML文件,包含了项目的基本信息,用于描述项目如何构建,声明项目依赖,等等。
- 执行任务或目标时,Maven 会在当前目录中查找 POM, 一般是 pom.xml 。它读取 POM,获取所需的配置信息,然后执行目标。
- 一个典型的 pom.xml , 该文件需要 project 元素和三个必需字段:groupId,artifactId,version。
<?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 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>org.example</groupId>
<artifactId>untitled2</artifactId>
<version>1.0-SNAPSHOT</version>
</project>
- project 工程的根标签。
- modelVersion 模型版本。
- groupId 工程组的标识。它在一个组织或者项目中通常是唯一的。
- artifactId 工程的标识。它通常是工程的名称。groupId 和 artifactId 一起定义了 artifact 在仓库中的位置。
- version 工程的版本号。
生命周期
- Maven 构建生命周期定义了一个项目构建跟发布的过程。
一个典型的 Maven 构建(build)生命周期是由以下几个阶段的序列组成的:
阶段 | 处理 | 描述 | |
---|---|---|---|
验证 | validate | 验证项目 | 验证项目是否正确且所有必须信息是可用的 |
编译 | compile | 执行编译 | 源代码编译在此阶段完成 |
测试 | test | 测试 | 使用适当的单元测试框架(例如JUnit)运行测试。 |
包装 | package | 打包 | 创建JAR/WAR包如在 pom.xml 中定义提及的包 |
检查 | verify | 检查 | 对集成测试的结果进行检查,以保证质量达标 |
安装 | install | 安装 | 安装打包的项目到本地仓库,以供其他项目使用 |
部署 | deploy | 部署 | 拷贝最终的工程包到远程仓库中,以共享给其他开发人员和工程 |
常用命令
mvn compile # 编译项目的源代码。
mvn test # 使用合适的单元测试框架运行测试(Juint是其中之一)。
mvn install # 安装项目包到本地仓库,这样项目包可以用作其他本地项目的依赖。
mvn deploy # 将最终的项目包复制到远程仓库中与其他开发者和项目共享。
mvn package # 将编译后的代码打包成可分发格式的文件,比如JAR、WAR或者EAR文件。
mvn tomcat:run # 启动Tomcat服务器
添加依赖
- 在 pom.xml 文件中配置依赖
<dependencies>
<dependency>
<groupId>commons-logging</groupId>
<artifactId>commons-logging</artifactId>
<version>1.2</version>
</dependency>
</dependencies>
使用
- groupId:属于组织的名称,类似Java的包名;
- artifactId:该jar包自身的名称,类似Java的类名;
- version:该jar包的版本。
通过上述3个变量,即可唯一确定某个jar包。Maven通过对jar包进行PGP签名确保任何一个jar包一经发布就无法修改。修改已发布jar包的唯一方法是发布一个新版本。 因此,某个jar包一旦被Maven下载过,即可永久地安全缓存在本地。
- 注:只有以-SNAPSHOT结尾的版本号会被Maven视为开发版本,开发版本每次都会重复下载,这种SNAPSHOT版本只能用于内部私有的Maven repo,公开发布的版本不允许出现SNAPSHOT。
依赖关系
Maven定义了几种依赖关系,分别是compile、test、runtime和provided:
scope | 说明 | 示例 |
---|---|---|
compile | 编译时需要用到该jar包(默认) | commons-logging |
test | 编译Test时需要用到该jar包 | junit |
runtime | 编译时不需要,但运行时需要用到 | mysql |
provided | 编译时需要用到,但运行时由JDK或某个服务器提供 | servlet-api |
其中,默认的compile是最常用的,Maven会把这种类型的依赖直接放入classpath。
- test依赖表示仅在测试时使用,正常运行时并不需要。最常用的test依赖就是JUnit:
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter-api</artifactId>
<version>5.3.2</version>
<scope>test</scope>
</dependency>
- runtime依赖表示编译时不需要,但运行时需要。最典型的runtime依赖是JDBC驱动,例如MySQL驱动:
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.48</version>
<scope>runtime</scope>
</dependency>
- provided依赖表示编译时需要,但运行时不需要。最典型的provided依赖是Servlet API,编译的时候需要,但是运行时,Servlet服务器内置了相关的jar,所以运行期不需要:
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
<version>4.0.0</version>
<scope>provided</scope>
</dependency>
仓库
仓库 是 Maven 下载所需依赖的地方,也就是存相关jar包的地方。
- Maven维护了一个中央仓库(repo1.maven.org),所有第三方库将自身的jar以及相关信息上传至中央仓库,Maven就可以从中央仓库把所需依赖下载到本地。
Maven 仓库有三种类型:
-
中央仓库 其实我们使用的大多数第三方模块都是这个用法,例如,我们使用commons logging、log4j这些第三方模块,就是第三方模块的开发者自己把编译好的jar包发布到Maven的中央仓库中。
-
私有仓库 私有仓库是指公司内部如果不希望把源码和jar包放到公网上,那么可以搭建私有仓库。私有仓库总是在公司内部使用,它只需要在本地的~/.m2/settings.xml中配置好,使用方式和中央仓位没有任何区别。
-
本地仓库 本地仓库是指把本地开发的项目“发布”在本地,这样其他项目可以通过本地仓库引用它。但是我们不推荐把自己的模块安装到Maven的本地仓库,因为每次修改某个模块的源码,都需要重新安装,非常容易出现版本不一致的情况。更好的方法是使用模块化编译,在编译的时候,告诉Maven几个模块之间存在依赖关系,需要一块编译,Maven就会自动按依赖顺序编译这些模块。
本地仓库(local)
Maven 的本地仓库,在安装 Maven 后并不会创建,它是在第一次执行 maven 命令的时候才被创建。 运行 Maven 的时候,Maven 所需要的任何构件都是直接从本地仓库获取的。如果本地仓库没有,它会首先尝试从远程仓库下载构件至本地仓库,然后再使用本地仓库的构件。
- 默认情况下,不管Linux还是 Windows,每个用户在自己的用户目录下都有一个路径名为 %HOME/.m2/respository/ 的仓库目录。
- Maven 本地仓库默认被创建在 %USERHOME% 目录下。要修改默认位置,在 %M2HOME%\conf 目录中的 Maven 的 settings.xml 文件中定义另一个路径。
<settings xmlns="http://maven.apache.org/SETTINGS/1.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/SETTINGS/1.0.0
http://maven.apache.org/xsd/settings-1.0.0.xsd">
<localRepository>/path/to/MyLocalRepository</localRepository>
</settings>
Idea 设置 Maven
如下:Settings -> Build,Execution,Deployment -> Build Tools -> Maven -> Maven home path