# Maven 使用其项目对象模型 Project Object Model 和一组插件构建项目
# Maven 是用 Java 开发的项目构建工具,可使项目构建过程中的依赖管理、编译、测试、部署、文档实现自动化
# 它提供了标准的、跨平台的自动化项目构建方式,并且能方便的管理
# 它定义了目录的结构,在通过 Maven 创建项目时以该目录结构作为模板进行创建
# ${basedir}
# |-- pom.xml # 项目描述文件、项目对象模型
# |-- src #
# | |-- main #
# | | `-- java # 项目源码所在: ${basedir}/src/main/java/<package>
# | | `-- resources # 项目资源文件所在
# | | `-- filters # 项目的资源过滤文件所在的目录
# | `-- test #
# | | `-- java # 测试代码所在
# | | `-- resources # 测试相关的资源文件所在
# | | `-- filters # 测试相关的资源过滤文件所在的目录
# | `-- it # 集成测试代码所在目录,主要是供别的插件使用的
# | `-- assembly # 组件 Assembly 描述符所在的目录
# | `-- site # 站点文件
# `-- LICENSE.txt # 项目的许可
# `-- NOTICE.txt # 该项目依赖的库的注意事项
# `-- README.txt # 项目的 readme
# target 目录: 主要用于存放项目构建的输出文件,如 class 文件及打包后的包文件等 ...
# ------------------------------------------------------------------------------- Maven 关键字
pom.xml
# Maven 的核心思想是 POM (项目对象模型) 即 Project Object Model,它是 Maven 项目中的XML文件
# 项目不仅是若干代码文件,一个项目往往包含一个配置文件,包括了与开发者有关的缺陷跟踪系统,组织与许可,项目URL,项目依赖及其他
# 它包含所有与该项目相关的东西,事实上在 Maven 世界中的 project 可以什么都没有,甚至没有代码,但必须有 pom.xml
# 它包含项目所需的所有信息,也就包含了构建过程中所需要的插件的配置信息,如: 源码、依赖、测试等 ...
# Maven 支持在项目构建的生命周期/阶段中集成各种插件 ...
构件
# 在 Maven 中任何一个依赖、插件、项目构建的输出都可称为构件:
# 如依赖 "log4j-1.2.15.jar" 是一个构件,插件 "maven-compiler-plugin-2.0.2.jar" 是一个构件
坐标
# 坐标为各种构件引入了秩序,每个构件都必须明确定义自身坐标
# 坐标是通过若干元素定义的,它们是: groupId、artifactId、version、packaging、class-sifer
# -------------------------------------- Example
<project>
<modelVersion>4.0.0</modelVersion>
# ...
<groupId>com.pastqing</groupId> # 当前项目的坐标
<artifactId>web-pay</artifactId> # 坐标由 groupId + artifactId + version 共同来组成全球唯一的标识
<packaging>jar</packaging> #
<version>1.0</version> #
# ...
<dependencies>
<dependency> # 依赖的坐标
<groupId>com.pastqing</groupId> # 是组织或项目的ID,通常使用项目的java包的根名作为groupID,如 com.pastqing
<artifactId>pay</artifactId> # 正在构建的项目名称, 如支付系统: pay,它是Maven仓库中groupId目录下的子目录名
<packaging>jar</packaging> # 项目产生的构件类型,如: jar、war、ear、pom
<version>1.0</version> # 构件的版本号
</dependency> # 在项目构建后会生成Jar包,以上三项都是构建结果名称的一部分
<dependency> # 其位于Maven仓库的路径为: MAVEN_REPO/com/pastqing/pay/1.0/pay-1.0.jar
# ......
</dependency>
</dependencies>
</project>
# ------------------------------------------------------------------------------- Repository
#
# [Maven 仓库] <=> [本地仓库]
# |
# *[远程仓库] # Tips: 借助坐标在各仓库中拉取、上传 Maven 构件...
# / | \
# [中央仓库] [私服] [其他公共库]
#
# -----------------------------------------------------
Maven 仓库的布局
# 得益于坐标机制,任何 Maven 项目使用任何一个构建的方式都是完全相同的
# Maven 能够在某个位置统一的存储所有 Maven 项目共享的构建(制品),这个位置就是仓库,项目构建后生成的构建也可以安装或部署到仓库中供其它项目使用
# 每个构件都有其唯一的坐标,根据该坐标可定义其在仓库中的唯一存储路径,这便是 Maven 的仓库布局方式 (Tips: Maven仓库是基于简单文件系统存储的)
# 仓库路径与坐标的大致对应关系为:<groupId>/<artifactId>/<version>/<artifactId>-<version>.<packaging>
# 如 log4j:log4j:1.2.16 这一依赖对应的仓库路径为:log4j/log4j/1.2.16/log4j-1.2.16.jar
Maven 仓库的分类
# 仓库分为两类:本地仓库、远程仓库
# 当根据坐标寻找构件时首先会查看本地仓库,若本地存在则直接使用此构件
# 若本地仓库不存在此构件,或需要查看是否有更新的版本时,将去远程仓库查找,找到对应的构件后下载到本地再使用
# 若本地和远程仓库都没有需要的构件,Maven 将会报错
# -----------------------------------------------------
本地仓库
# 特指用户本机中的的仓库,默认路径为 ${HOME}/.m2/repository
# 可通过编辑 Maven 配置文件 settings.xml 中的 localRepository 元素的值来修改本地仓库的路径:
# ......
# <localRepository>D:\Soft\maven\maven_jar\repository</localRepository>
# ......
远程仓库
# 远程仓库相对本地仓库,本地仓库不存在的构件才会从远程仓库下载并保存到本地仓库
# 对 Maven 来说只能有一个本地仓库,但可配置多个远程仓库
中央仓库
# Maven 必须知道至少一个可用的远程仓库才能在执行 maven 命令时下载需要的构件,这个中央仓库就是默认的远程仓库
# 中央仓库的信息在超级 Pom 中配置,所有maven项目都会继承超级 POM
# 超级POM的定义: $M2_HOME/lib/maven-model-builder-3.0.jar,将其解压后访问路径: org/apache/maven/model/pom-4.0.0.xml
# <repositories>
# <repository>
# <id>central</id> # 使用 central 对仓库进行唯一标识
# <name>Central Repository</name> # 仓库名称
# <url>https://repo.maven.apache.org/maven2</url> # 仓库地址
# <layout>default</layout> # 指定仓库的布局,default 也就是上面提到布局规则
# <snapshots>
# <enabled>false</enabled> # 表示不从该仓库下载快照版本的构件
# </snapshots>
# </repository>
# </repositories>
私服
# 私服是种特殊的远程仓库,它是架设在局域网的仓库服务,它代理互联网上的远程仓库供内部局域网使用
三种添加构件到本地仓库的方式
从远程仓库下载
# 通过在项目的 pom.xml 中配置 dependency 依赖,将下载需要的依赖到本地仓库 ...
通过maven命令安装构件到本地仓库
# 在 maven 项目根目录执行 "mvn clean install" 命令即可将项目以构件形式安装到本地仓库中
安装第三方构件到本地仓库
# 例如别人开发好的一个 jar 包还未发布到maven的中央仓库时,其他人此时要在maven项目中使用该Jar包的场景
# 此时可通过命令将该 jar 包添加到本地仓库中,这样就能在项目中声明使用了,Tips: 声明一个构件需要: groupId\artifactId\version
# ---------------------------------------------------------- Example
# 假设需将jar包 "g:\edu.mit.jwi_2.3.3_jdk.jar" 安装到本地仓库:
# 先自定义jar的坐标信息:
# gourpId=local.edu.stanford
# artifactId=edu.mit.jwi_jdk
# version=2.3.3
# packaging=jar
#
# 然后在命令行中执行如下即可:
# mvn install:install-file \
# -Dfile=g:\edu.mit.jwi_2.3.3_jdk.jar \
# -DgroupId=local.edu.stanford \
# -DartifactId=edu.mit.jwi_jdk \
# -Dversion=2.3.3 \
# -Dpackaging=jar
在 pom.xml 中配置远程仓库
<!-- 默认的中央仓库有时无法满足项目需求,可能需要的构件在其他的远程仓库,如 JBoss Maven 仓库,可以在POM中配置该仓库 -->
<repositories> 在 repositories 元素内使用子元素: repository 声明若干远程仓库
....
<repository>
<id>jboss</id> 声明ID为jboss、名称为 JBoss Repository 的仓库
<name>JBoss Repository</name>
<url>https://repository.jboss.com/maven2/</url>
<layout>default</layout>
<snapshots>
<enabled>false</enabled> 不从该仓库下载快照版本的构件
<updataPolicy>daily</updataPolicy>
</snapshots>
<releases>
<enabled>true</enabled> 开启此仓库的发布版本下载支持
<updataPolicy>daily</updataPolicy> 设置Maven从远程仓库检查更新的频率,默认每天检查一次
</releases> 对同一版本构件若发现有更新(如对 log4j.1.2.15.jar 进行内容修复但版本不变)则下载最新的
</repository>
....
</repositories> 根据以上配置,maven只从这个JBoss仓库下载发布版本的构件,不会下载快照版本
在 Maven 的 settings.xml 中配置镜像仓库
# 如果仓库 X 可以提供仓库 Y 存储的所有内容,那么就可以认为 X 是 Y 的镜像
# 镜像常用于私服,因为私服代理了任何外部的公共仓库,所以对于组织内部的 Maven 用户来说使用一个私服地址就等于使用了所有的外部仓库
# 使用阿里云镜像替换中央仓库
# 使用阿里云的镜像: http://maven.aliyun.com/nexus/content/groups/public/ 替换中央仓库: http://repol.maven.org/maven2/
<settings>
<mirrors>
<mirror>
<id>alimaven</id>
<name>aliyun maven</name>
<url>http://maven.aliyun.com/nexus/content/groups/public/</url>
<mirrorOf>central</mirrorOf>
# 上述设置表示该配置为中央仓库镜像,任何对中央仓库的请求都转至该镜像,也可使用该方法配置其它仓库的镜像
</mirror>
</mirrors>
</settings>
# -----------------------------------------------------
# 为满足复杂需求,Maven 还支持更高级的镜像配置
# <mirrorOf>*</mirrorOf>: 匹配所有远程仓库,作为它们的镜像
# <mirrorOf>external:*</mirrorOf>: 匹配所有远程仓库,使用 localhost、使用 file:// 协议的除外
# <mirrorOf>repo1,repo2</mirrorOf>: 匹配 repo1,repo2 仓库,多个仓库使用逗号分隔
# <mirrorOf>*,!repo1</mirrorOf>: 匹配所有远程仓库,repo1 除外
远程仓库的认证
# 出于安全考虑,需提供认证信息才能访问某些远程仓库
# 认证配置不在 pom.xml,而是在 settings.xml 中,因为Pom会被提交到代码仓库中供所有成员访问,而 settings.xml 通常只在本机
# 假设在 pom.xml 中配置了 id=my-proj 的远程仓库需要认证,则在 settings.xml 中配置如下:
# ----------------------------------------------------- Example
<settings>
......
# settings.xml 的 servers 用来配服务器授权,不仅配置仓库认证,还可配置其它如tomcat服务器授权信息 ...
<servers>
<server>
<id>my-proj</id> # 仓库ID
<username>repo-user</username> # 账号
<password>repo-pwd</password> # 密码
</server>
</servers>
......
</settings>
从仓库解析依赖的机制
# 当依赖范围是 system 时 Maven 直接从本地文件解析构件
# 根据依赖坐标计算仓库路径后,先从本地仓库寻找构件,如果发现则解析成功
# 当本地仓库没找到时,若依赖版本 "version" 是发布版构件,即 1.2,2.3 等,则遍历远程仓库,发现后下载并解析使用
# 如果 version是 "SNAPSHOT" 版,如: 2.1-SNAPSHOT,则基于更新策略 "update policy" 读取所有远程仓库的元数据: groupId/artifactId/version/maven-metadata.xml
# 将其与本地仓库的对应元数据合并后,得到最新快照版本的值,然后基于该值检查本地仓库或从远程仓库下载(如果最新版还是之前的值就不需去远程仓库下载了)
Theory
# 环境变量 MAVEN_OPTS 包含用于启动运行 Maven 的 JVM 参数
# 例如JVM内存设置 -Xms256m -Xmx512m