本文概览
Maven的定义
Maven是一个用于构建(Build)、发布(Publish)、管理(Manage)Java项目的强大工具。它提供了一种标准的项目结构和构建流程,使得Java项目的开发、构建和管理更加简单和一致。
Maven解决了什么问题
在没有Maven前,Java的应用构建存在了哪些问题?
- 手动构建: 开发者需要手动编译Java源代码、打包应用等。这需要大量的重复工作,并容易引入错误。
- 依赖管理混乱: 管理外部依赖通常需要手动下载JAR文件、将它们放置在适当的位置,并手动配置类路径。这容易导致版本冲突和混乱。
- 构建差异: 不同项目的构建流程可能不同,导致了构建流程的差异化和项目结构的不一致。
- 项目结构不一致: 没有明确的标准项目结构,开发者可以根据他们自己的偏好组织项目,这导致了项目之间结构的不一致。
- 可维护性差: 缺乏一种标准的方式来组织和管理项目,这使得项目的可维护性较差,尤其是在大型项目中。
- 版本控制问题: 项目的依赖关系和构建设置通常需要版本控制,但手动管理这些文件可能会引入冲突和错误。
- 缺乏标准化工具: 缺乏一种标准化的工具或流程来自动化构建、测试和部署,开发者需要自己开发或维护这些工具。
Maven的出现解决了上述问题,它引入了标准的项目结构、依赖管理、构建生命周期和插件体系,使得Java应用的构建变得更加一致、自动化和可维护。
Maven的构建过程
Maven的构建过程是分阶段的,通常包括清理(clean)、编译(compile)、测试(test)、打包(package)、安装(install)、部署(deploy)等阶段。
如图,Lifecycle
指的是构建过程中不同的阶段。而Plugins
提供的是在不同阶段执行不同目标的操作。
在Lifecycle
中,Maven能做的事如下:
- 清理(clean):删除编译的结果,为重新编译做准备。
- 验证(validate):验证项目是否正确且所有必须信息是可用的。
- 编译(cpmpile):源代码编译成字节码文件
- 测试(test):针对于项目中的关键点进行测试,也可用项目中的测试代码去测试开发代码
- 打包(package):将项目中包含的多个文件压缩成一个文件,用于安装或部署(java项目打成一个jar包,web项目打成一个war包,父工程-pom)
- 检查(verify):对集成测试的结果进行检查,以保证质量达标
- 安装(install):将打成的包,放到本地仓库,供其他项目使用。
- 部署(deploy):将打成的包,放到服务器上,准备运行。
Maven的重要概念
- 项目对象模型(Project Object Model,POM): Maven使用POM文件(通常是pom.xml)来描述项目的结构和构建配置。POM文件包含了项目的依赖关系、插件配置、构建目标等信息。
- 依赖管理: Maven可以自动管理项目的依赖关系。你可以在POM文件中声明需要的外部库,Maven会自动下载和管理这些库的版本,并确保它们在构建和运行时可用。
- 生命周期和插件: Maven定义了一组构建生命周期(如clean, compile, test, package等),每个生命周期包含一系列构建目标。插件是执行这些目标的工具,你可以配置插件来执行各种任务,如编译、测试、打包等。
- 中央仓库: Maven有一个中央仓库,其中包含了大量的开源Java库和插件。你可以从中央仓库下载依赖,无需手动管理库的获取和版本升级。
- 多模块支持: Maven支持构建多模块项目,每个模块可以有自己的POM文件,但它们可以共享依赖关系、插件配置和构建设置。
- 插件生态系统: Maven有丰富的插件生态系统,你可以使用现有插件或编写自定义插件来扩展和自定义构建过程。
- 一致的目录结构: Maven鼓励项目遵循一致的目录结构,使得项目更容易管理和理解。
总结:POM.xml
本质上是对项目信息的一种抽象,Maven基于POM对项目进行依赖管理,自动获取依赖的JAR包,并可以通过配置的方式解决依赖冲突问题。
其实项目中依赖管理是比较麻烦的,特别是手动引入的时候容易造成版本冲突问题。那么maven提供一种方式,我们把依赖包都放到一个仓库中Repository。
每个Maven项目中,都会有一个POM(Project Object Model)的文件,上面清晰的定义了项目的一些元信息、配置和依赖。那么Maven可以基于POM自动的从仓库中奖相应的依赖与项目进行关联,并通过Maven构建一件打包,部署上线。
这里对Mavne的仓库进行简单说明:
- 本地仓库 : 相当于缓存。本地仓库存储在本地的磁盘当中,里面存放的是经常使用的JAR包。
- 远程仓库 : 也叫做私服。基本每个公司都会有自己的私服,当本地的磁盘中不存在需要的JAR包资源,则会请求私服进行资源下载。
- 中央仓库 : 远程仓库,由Maven专业团队统一维护。
中央仓库地址:
Maven Repository
Maven项目
创建Maven项目需要使用Maven的(Archetype )原型机制。那么什么是原型机制呢?
”原型被定义为一种原始模式或模型,所有其他同类事物都是由它构成的。在 Maven 中,原型是一个项目模板,它与一些用户输入相结合,生成一个根据用户需求定制的工作 Maven 项目。“
我们就把它理解为模板就行。现在来看Maven项目POM
文件的构成
<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>com.mycompany.app</groupId>
<artifactId>my-app</artifactId>
<version>1.0-SNAPSHOT</version>
<name>my-app</name>
<!-- FIXME change it to the project's website -->
<url>http://www.example.com</url>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<maven.compiler.source>1.7</maven.compiler.source>
<maven.compiler.target>1.7</maven.compiler.target>
</properties>
<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.11</version>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<pluginManagement><!-- lock down plugins versions to avoid using Maven defaults (may be moved to parent pom) -->
... lots of helpful plugins
</pluginManagement>
</build>
</project>
pom.xml
包含该项目的项目对象模型 (POM
)。POM
是 Maven 中的基本工作单元。 Maven 本质上是以项目为中心的。POM
包含有关项目的重要信息。
上面是一个非常简单的 POM
,逐一介绍里面的元素:
project
**这是所有 Mavenpom.xml
文件中的顶级元素。modelVersion
该元素指示该POM
使用的对象模型的版本。模型本身的版本很少更改,但是当 Maven 开发人员**认为有必要更改模型时,为了确保使用的稳定性,这是强制性的。groupId
该元素指示创建项目的组织或组的唯一标识符。groupId 是项目的关键标识符之一,通常基于组织的完全限定域名。例如org.apache.maven.plugins
为所有 Maven 插件指定的 groupId。artifactId
此元素指示由该项目**生成的artifact
的唯一基本名称。Maven 生成的包名的格式为<artifactId>-<version>.<extension>
(例如,myapp-1.0.jar
)。version
** **此元素指示项目生成的artifact
的版本。Maven 在很大程度上帮助沃恩进行版本管理,在开发中经常会看到SNAPSHOT
,这表明这个包只是一个测试版本。name
此元素指示用于项目的显示名称。这在 Maven 生成的文档中经常使用。url
该元素指示可以找到项目站点的位置。这在 Maven 生成的文档中经常使用。property
用于创建POM
中的变量,在文件中可以通过引用变量的方式来赋值。dependencies
存放依赖的地方,每个标签都是一个依赖build
该元素处理诸如声明项目的目录结构和管理插件之类**的事情。
我们通过ArcheType生成项目的结构一般为:
my-app
|-- pom.xml
`-- src
|-- main
| `-- java
| `-- com
| `-- mycompany
| `-- app
| `-- App.java
`-- test
`-- java
`-- com
`-- mycompany
`-- app
`-- AppTest.java
这是Maven的标准项目目录,有源分支和测试分支。POM.xml
存放于${project.basedir}
中。我们的应用源码一般放在${project.basedir}/src/main/java
,测试源码放在${project.basedir}/src/test/java
。
项目编译
当我们对项目进行编译时,Maven会下载所有的插件和项目相关的依赖。编译之后的类文件都会放在${project.basedir}/target/classes
中,这也是一个Maven 标准格式的文件夹。
依赖管理
管理依赖的标签为dependencyManagement
和dependencies
。
dependencyManagement
- 定义依赖信息,在后续引入依赖时不用重复定义version、scope等
- 在此处定义的依赖无法直接生效,只是作为管理使用
dependencies
- 节点中定义的依赖在编译时build,自动会引入此包到路径下
- 除非在dependencyManagement中有定义版本,否则版本不能为空
总结:Management作为管理,只是将项目所需要的依赖进行列举,最终使用需要dependencies标签中定义。