Maven简介
Maven是一个异常强大的构建工具,能够帮我们自动化构建过程,从清理、编译、测试到生成报告,再到打包和部署。
Maven将项目构建的过程进行标准化,每一个阶段使用一个命令完成。
Maven 依赖管理
一个Java项目可能需要使用第三方的jar包才可以运行,那么我们就说这个Java项目依赖了这些第三方jar包。传统的项目工程要管理所依赖的jar包完全靠人工运行,需要手动将jar包添加到项目工程中,导致工作量繁重,工程体积过大。
Maven项目管理所依赖的jar包不需要手动向工程中添加jar包,只需要在pom.xml
添加jar包的坐标,自动从Maven仓库下载jar包、运行。
Maven 标准目录结构
|-src
| |-main
| | |-java —— 存放项目的.java文件
| | |-resources —— 存放项目资源文件,如spring, hibernate配置文件
|-webapp —— webapp目录是web工程的主目录
|-WEB-INF
|-web.xml
| |-test
| |-java —— 存放所有测试.java文件,如JUnit测试类
| |-resources —— 测试资源文件
|-target —— 目标文件输出位置例如.class、.jar、.war文件
|-pom.xml —— maven项目核心配置文件
Maven仓库
- 本地仓库:用来存储从远程仓库或者中央仓库下载的插件和jar包,项目使用的一些插件或者jar包,优先从本地仓库查找
- 远程仓库:如果本地仓库需要插件或者jar包,本地仓库没有,默认去远程仓库下载,远程仓库可以在互联网内也可以在局域网内
- 中央仓库:在maven软件中内置的一个远程仓库的地址,它是中央仓库,里面存储了非常全的jar包,包含了世界上大部分流行的开源项目构件
Maven 命令
- complie:Maven工程的编译命令,将
src/main/java
下的文件编译为class
文件输出到target
目录下 - test:Maven工程的测试命令,会执行
src/test/java
下的单元测试类 - clean:Maven工程的清理命令,执行会删除
target
目录下的内容 - package:Maven工程的打包命令,对于Java工程执行
package
会打成jar
包,Web工程会打成war
包 - install:Maven工程的安装命令,执行会把Maven打成
jar
或war
包发布到本地仓库
Maven生命周期
Maven拥有三套相互独立的生命周期,它们分别是clean
default
site
- clean 生命周期的目的是清理项目
pre-clean
:执行一些需要在clean之前完成的工作clean
:清理所有上一次构建生成的文件post-clean
:执行一些清理后需要完成的工作
default
生命周期定义了真正构建时所需要的执行的所有步骤,是所有生命周期中最核心的部分- validate
- initialize
- generate-sources
- process-sources 处理项目主资源文件
- generate-resources
- process-resources
- compile:编译项目的主源码
- process-classes
- generate-test-sources
- process-test-sources:处理项目测试资源文件
- generate-test-resources
- process-test-resources
- test-compile:编译项目的测试代码
- process-test-classes
- test:使用单元测试框架运行测试,测试代码不会被打包或者部署
- prepare-package
- package:接收编译好的代码,打包成可发布的格式
- pre-integration-test
- integration-test
- post-integration-test
- verify
- install:将包安装到Maven本地仓库
- deploy:将包复制到远程仓库
site
生命周期的目的是建立和发布站点- pre-site:执行一些在生成项目站点之前需要完成的工作
- site:生成项目站点文档
- post-site:执行一些在生成项目站点之后需要完成的工作
- site-deploy:将生成的项目站点发布到服务器上
Maven的概念模型
Maven包含了一个项目对象模型(Project Object Model),一组标准集合,一个项目生命周期(Project Lifecycle),一个依赖管理系统(Dependency Manngement System)和用来运行定义在生命周期阶段中插件目标的逻辑。
-
项目对象模型
一个Maven工程有一个
pom.xml
文件,通过pom.xml
文件定义项目的坐标、项目依赖、项目信息、插件目标等 -
依赖管理系统
通过Maven的依赖管理系统对项目所依赖的jar包进行统一管理
例如:项目依赖
junit4.9
,通过在pom.xml
中定义junit4.9
的依赖即使用junit4.9
,如下所示是对junit4.9
的依赖定义<!-- 依赖关系 --> <dependencies> <!-- 此项目运行使用junit,所以此项目依赖junit --> <dependency> <!-- junit的项目名称 --> <groupId>junit</groupId> <!-- junit的模块名称 --> <artifactId>junit</artifactId> <!-- junit版本 --> <version>4.9</version> <!-- 依赖范围:单元测试时使用junit --> <scope>test</scope> </dependency>
-
一个项目生命周期
清理 –>编译 –> 测试 –> 报告 –> 打包 –> 部署
-
一组标准集合
Maven将整个项目管理过程定义一组标准,比如:通过Maven构建工程有标准的目录结构,有标准的生命周期阶段、依赖管理有标准的坐标定义
-
插件目标
Plugin Goal
Maven的核心仅仅定义了抽象的生命周期,具体的任务是交由插件完成的,插件以独立的构件形式存在。Maven的生命周期和插件相互绑定,用以完成实际的任务。具体而言,是生命周期的阶段与插件的目标相互绑定,以完成某个具体的构建任务。例如项目编译这一个任务,它对应了
default
生命周期的compile
这一个阶段,而maven-compiler-plugin
这一个插件的compile
目标能够完成任务,因此将它们绑定,就能实现项目编译的目的。
Maven工程的拆分与聚合
为达到拆分和聚合的目的,引入父工程maven project
和模块maven module
父工程本身不写代码,它里面有一个pom.xml
文件,这个文件可以将多个子模块中通用的jar所对应的坐标,集中在父工程中配置,将来的子模块就可以不需要在pom.xml
中配置通用的jar的坐标了。
冲突问题的解决
-
通过添加
<exclusion>
标签来解决冲突<dependency> <groupId>org.apache.struts</groupId> <artifacId>struts2-core</artifacId> <version>2.3.24</version> <exxlusions> <exclusion> <srtifactId>javassist</srtifactId> <groupId>javassist</groupId> </exclusion> </exxlusions> </dependency>
-
使用版本锁定解决冲突
<dependencyManagement> <dependencies> <!-- 这里锁定版本为4.2.4 --> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-beans</artifactId> <version>4.2.4.RELEASE</version> </dependency> </dependencies> </dependencyManagement>
依赖调节原则
-
第一声明者优先原则
在
pom.xml
文件定义依赖,先声明的依赖为准 -
路径近者优先原则
A依赖XXX,A依赖B依赖XXX,则XXX优先被依赖在A中