Maven 简介

Apache Maven是专门用于管理和构建Java项目的工具, 它基于项目对象模型 (POM) 的概念, 通过一小段描述信息来管理项目的构建, 报告和文档.

Maven的主要功能有:

  • 提供了一套标准化的项目结构.
  • 提供了一套标准化的构建流程 (编译, 测试, 打包, 发布…).
  • 提供了一套依赖管理机制.

Maven 模型

Maven模型包含:

  • 项目对象模型 (Project Object Model)
  • 依赖管理模型 (Dependency)
  • 插件 (Plugin)

Maven模型图示:

其中紫色框框起来的部分, 就是用来完成标准化构建流程.

仓库

Maven仓库是项目中依赖的第三方库, 这个库所在的位置叫做仓库 (在Maven的术语中,仓库是一个位置, place).

Maven中, 任何一个依赖、插件或者项目构建的输出,都可以称之为构件. Maven仓库能帮助我们管理构件 (主要是JAR), 它就是放置所有JAR文件 (WAR, ZIP, POM等等) 的地方.

仓库有三种类型:

  • 本地 (local)
  • 中央 (central)
  • 远程 (remote)

在项目中使用坐标引入对应依赖jar包后, Maven会按照本地仓库 –> 远程仓库–> 中央仓库的顺序去查找相应的jar包. 只要jar包存在, 如果是在本地仓库则直接使用, 而如果在远程仓库或中央仓库, Maven则将jar包自动下载到本地仓库.

本地仓库

本地仓库在第一次执行maven命令的时候才被创建.

运行 Maven 的时候, Maven 所需要的任何构件都是直接从本地仓库获取的. 如果本地仓库没有, 它会首先尝试从远程仓库下载构件至本地仓库, 然后再使用本地仓库的构件.

Maven 本地仓库默认为用户主目录 (USER HOME) 中的 .m2/repository.

中央仓库

Maven 中央仓库是由 Maven 社区提供的仓库, 其中包含了大量常用的库.

中央仓库包含了绝大多数流行的开源Java构件, 以及源码、作者信息、SCM、信息、许可证信息等. 一般来说,简单的Java项目依赖的构件都可以在这里下载到.

Maven 社区提供了一个 URL: search.maven.org/#browse, 来浏览中央仓库的内容.

远程仓库

远程仓库是开发人员自己定制的仓库, 包含了所需要的代码库或者其他工程中用到的 jar 文件. 一般是由公司团队搭建的私有仓库.


Maven标准化项目结构

Maven提供了一套标准化的项目结构, 所有的IDE使用Maven构建的项目完全一样. 所以, 使用Maven创建的项目在所有IDE中可以通用.

使用Maven构建的项目结构示例:

  • 📁project_name — 项目主目录
    • 📁src — 源代码和测试代码文件目录
      • 📁main — 源代码文件目录
        • 📁java — 源代码Java文件目录
        • 📁resourcs — 源代码配置文件目录
      • 📁test — 测试代码文件目录
        • 📁java — 测试代码Java文件目录
        • 📁resource — 测试代码配置
      • 📄pom.xml — 项目核心配置文件

项目核心配置文件 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>4.0.0</modelVersion>

  <!-- The Basics -->
  <!-- 公司或者组织的唯一标志 -->
  <groupId>...</groupId>
  <!-- 当前项目唯一ID -->
  <artifactId>...</artifactId>
  <!-- 本项目目前所处的版本号 -->
  <version>...</version>
  <!-- 打包的机制 -->
  <packaging>...</packaging>
  <!-- 项目依赖关系 -->
  <dependencies>...</dependencies>
  <parent>...</parent>
  <dependencyManagement>...</dependencyManagement>
  <modules>...</modules>
  <!-- pom常量 -->
  <properties>...</properties>

  <!-- Build Settings -->
  <build>...</build>
  <reporting>...</reporting>

  <!-- More Project Information -->
  <!-- 项目的名称 -->  
  <name>...</name>
  <!-- 项目的详细描述 -->
  <description>...</description>
  <!-- 项目主页的URL -->
  <url>...</url>
  <inceptionYear>...</inceptionYear>
  <licenses>...</licenses>
  <organization>...</organization>
  <developers>...</developers>
  <contributors>...</contributors>

  <!-- Environment Settings -->
  <issueManagement>...</issueManagement>
  <ciManagement>...</ciManagement>
  <mailingLists>...</mailingLists>
  <scm>...</scm>
  <prerequisites>...</prerequisites>
  <!-- 发现依赖和扩展的远程仓库列表 -->
  <repositories>...</repositories>
  <pluginRepositories>...</pluginRepositories>
  <distributionManagement>...</distributionManagement>
  <profiles>...</profiles>
</project>

pom.xml中描述符的根为<project>.

Maven坐标

  • Maven 中的坐标是资源的唯一标识.
  • 使用坐标来定义项目引入项目中需要的依赖.

Maven坐标的主要组成 (在pom.xml文件中):

  • <groupId>: 公司或者组织的唯一标志. 配置时生成的路径也是由此生成. 如com.linner.blog (通常是域名反写), Maven会将该项目打成的jar包放本地路径:/com/linner/blog.
  • <artifactId>: 当前项目的唯一ID (通常是模块名称). 一个groupId下面可能多个项目, 就是靠<artifactId>来区分.
  • <version>: 本项目目前所处的版本号.

Maven 中, 根据 groupIdartifactIdversion 组合成 groupId:artifactId:version 来唯一识别一个 jar 包. 这三个标签构成了Maven坐标.

其他基本配置

  • <modelVersion>: 指定pom.xml符合哪个版本的描述符. Maven2和3只能为4.0.0.
  • <packaging>: 打包的机制. 有以下几种:
    • pom
    • jar — 默认值
    • maven-plugin
    • ejb
    • war
    • ear
    • rar
    • par
  • <dependencies>: 定义本项目的依赖关系.

Maven依赖管理

依赖管理是指管理项目中所依赖的第三方资源 (jar包, 插件). 而Maven使用标准的坐标配置来管理各种依赖, 只需要简单的配置就可以完成依赖管理.

Maven的依赖资源是在pom.xml配置文件中的<dependencies>描述的. 其结构如下:

  • <project>
    • <dependencies>
      • <dependency>: 一个<dependency>代表一个依赖项. <groupId>, <artifactId><version>的含义与<project>的子标签<groupId>, <artifactId><version>的含义相同.
        • <groupId>
        • <artifactId>
        • <version>
        • <type>: 依赖的打包机制. 对应<packaging>的类型, 有pom, jar(默认), maven-plugin, ejb, war, ear, rar, par.
        • <scope>: 任务的类路径 (编译和运行时, 测试等) 以及如何限制依赖关系的传递性.
          scope取值 有效范围(compile, runtime, test) 依赖传递
          compile all
          provided compile, test
          runtime runtime, test
          test test
          system compile, test
        • <optional>
        • <exclusions>
          • <exclusion>
            • <groupId>
            • <artifactId>
          • <exclusion>
          • 多个<exclusion>
      • 多个<dependency>

<scope>取值说明:


Maven常用命令

  • compile: 编译
  • clean: 清理
  • test: 测试
  • package: 打包
  • install: 安装

使用Maven命令需要先配置PATH, 然后在项目目录下执行.

例如项目路径为~/project:

cd ~/project

编译

mvn compile

第一次执行该命令, Maven会自动从仓库 (中央仓库或远程仓库, 介绍常用命令时, 如无特别指出, 仓库均指中央仓库或远程仓库) 下载编译所需的jar插件包. 然后在项目下会生成一个 target 目录. 编译后的字节码文件就放在该目录下.

清理

mvn clean

第一次执行该命令, Maven会从仓库下载清理所需要的jar插件包. 接着便使用插件清除项目下的target目录.

打包

mvn package

第一次执行该命令, Maven会从仓库下载打包所需要的jar插件包. 然后在项目的 terget 目录下生成一个jar包 (将当前项目打成的jar包).

测试

mvn test

该命令会执行所有的测试代码, 即project/scr/text下的代码.

安装

mvn install

该命令会将当前项目打成jar包, 并安装到本地仓库. 执行完上述命令后可以到本地仓库查看结果. 仓库中的路径为pom.xml文件中<groupId>相应的路径, 生成的jar包名为<artifactId><version>组成的内容.


Maven生命周期

Maven 构建项目生命周期描述的是一次构建过程经历经历了多少个事件.

Maven对项目构建的生命周期划分为3套:

  • clean: 清理工作.
  • default: 核心工作, 例如编译, 测试, 打包, 安装等.
  • site: 产生报告, 发布站点等. 这套声明周期一般不会使用.

同一套生命周期内, 执行后边的命令, 前面的所有命令会自动执行.

default 生命周期如下:

如执行install命令, maven会按照上图中从左到右的顺序先执行compile, 再执行test, package, 最后执行install; 如果执行package, 除了install命令, 其它命令按照上图左到右顺序执行.

默认的生命周期其实有对应的很多命令, 上图中只展示了常用的.