一、Maven简介
Maven翻译为“专家”,是Apache下的一款跨平台的开源项目管理工具。主要服务于基于Java平台的项目构建、依赖管理和项目信息管理。
构建工具(Build)
每天除了编写源码,程序员相当一部分时间花在编译、运行单元测试,生产文档,打包和部署等构建工作上。Maven可抽象构建声明周期模型,并标准化构建过程。
依赖管理工具
提供中央仓库,自动下载构建(artifact),Maven可有序的管理依赖,并且管理原本分散在项目各个角落的项目信息。并提供了大把现成的插件。
敏捷开发之极限编程(XP)中,Maven的价值:
- 简单
- 测试驱动开发(TDD)
- 十分钟构建(清理、编译、测试、打包、部署、产品)
- 持续集成(CI)
其他构建工具有Gradle,Make(makefile脚本),Ant(build.xml)。而Maven使用pom.xml,pom作为项目对象模型。
二、Maven概念
坐标
Maven通过groupId、artifactId、version、packaging等元素来构成坐标。
1 | <groupId>com.herr</groupId> |
依赖
1、配置
1 | <project> |
2、scope依赖范围
classpath有3套,分别是编译classpath、测试classpath、运行classpath。Maven的依赖范围scope对应关系如下:
- compile,默认,三种classpath都有效。
- test,只对于测试classpath有效。比如JUnit。
- provided,对编译和测试classpath有效,如servlet-api。
- runtime,对于测试和运行classpath有效。如JDBC驱动
- system,和provided依赖范围一致,但通过systemPath指定依赖文件路径。
3、传递型依赖
依赖范围影响传递性依赖,可选依赖不被传递。
依赖调解原则:
- 路径最近者优先
- 第一声明者优先
4、依赖优化
- 排除依赖
- 归类依赖(使用Maven属性-properties)
- 优化依赖
1 | $ mvn dependency:list |
仓库
1、仓库分为本地仓库和远程仓库。
本地仓库的原始路径:/.m2/repository,用户可在/.m2/settings.xml中设置localRepository属性来设置本地仓库地址。
Maven寻找构建时,会先检查本地仓库,如有直接使用,如没有则下载到本地仓库再使用。可使用mvn clean install命令将项目的构建输出文件安装到本地仓库。
远程仓库包括中央仓库、私服和其他第三方仓库。
可通过pom中的repositories属性来配置远程仓库。通过setting.xml中配置仓库认证信息。在认证后,可使v用命令mvn clean deploy部署到配置对应的远程仓库。
如gradle本地仓库需要和MAVEN共用,可设置系统环境变量GRADLE_USER_HOME。
2、部署私服,优点有:
- 节约外网带宽
- 加速Maven构建
- 部署第三方构建
- 提高稳定性,增强权限等控制
- 降低中央仓库符合
可使用Nexus(推荐)、Archeiva、Artifactory等开源版本来部署私服。
3、仓库搜索服务
可通过『Sonatype Nexus』 、『Jarvana』 、『MVNbrowser』 、『MVNrepository』 、『阿里云云效Maven』等方式来搜索。
4、仓库镜像
可通过编辑settings.xml来配置Maven镜像来替代中央仓库,或者配置使用私服。
1 | <settings> |
生命周期(Lifecycle)
生命周期包含了项目的清理、初始化、编译、测试、打包、集成测试、验证、部署和站点生成等所有构建步骤。生命周期是抽象的,每个构建步骤绑定了一个或多个插件行为,实际任务交由对应的插件(plugin)来完成。
Maven有三套独立的生命周期,分别为clean(清理项目)、default(构建项目)和site(简历项目站点)。
1、clean生命周期
- pre-clean
- clean
- post-clean
2、default生命周期(常用)
- process-resources,处理项目主资源文件,src/main/resources目录
- compile,编译项目的主源码,src/main/java目录
- process-test-resources,处理项目测试资源文件,src/test/resources目录
- test-compile,编译项目的测试代码,src/test/java目录
- test,使用单元测试框架运行测试,不会打包或部署
- package,接受编译好的代码,打包成可发布的格式(如JAR)
- install,将包安装到Maven本地仓库
- deploy,将包复制到远程仓库
3、site生命周期
- pre-site
- site,生成项目站点文档
- post-site
- site-deploy,发布到服务器
命令行与生命周期的关系:
- mvn clean,调用生命周期的clean阶段,调用pre-clean和clean。
- mvn test,调用defaul周期的test阶段,调用validate、initialize,直到test所有阶段
- mvn clean install
- mvn clean deploy site-deploy
插件(Plugin)
插件目标:一个插件有多个功能,每一个功能对应了一个插件目标。
Maven的声明周期和插件目标相互绑定,用以完成实际的构建任务。用户也可自行使用MOJO(Maven Old Java Object)实现编写插件。
内置绑定中,默认对应关系如下,用户可从Maven命令行输出中查看执行了哪些插件目标。
声明周期阶段 | 插件目标 | 执行任务 |
---|---|---|
pre-clean | maven-clean-plugin:clean | |
clean | maven-clean-plugin:clean | |
post-clean | maven-clean-plugin:clean | |
pre-site | maven-site-plugin:site | |
site | maven-site-plugin:site | |
post-site | maven-site-plugin:site | |
site-deploy | maven-site-plugin:deploy | |
process-resources | maven-resources-plugin:resources | |
process-test-resources | maven-resources-plugin:testResources | |
compile | maven-compiler-plugin:compile | |
test-compile | maven-compiler-plugin:testCompile | |
test | maven-surefire-plugin:test | |
package | maven-jar-plugin:jar | |
install | maven-install-plugin:install | |
deploy | maven-deploy-plugin:deploy |
插件配置:
1、通过命令行插件配置,使用-D命令来配置插件目标的参数。
1 | $ mvn install -Dmaven.test.skip=true |
2、POM中插件全局配置。本例中,是maven-compiler-plugin的compile任务还是testCompiler任务,都可以使用该配置生成1.5版本的源文件和字节码。
1 | <build> |
3、POM中插件任务配置,可通过executions配置自定义插件,在不同生命阶段执行不同的任务。如本例中在verify阶段打包代码。
1 | <build> |
可通过『Apache Maven Plugins文档』来获取所有插件信息。
用户不需要提供完整的插件坐标信息。Maven有内置的插件仓库配置,默认的groupId为org.apache.maven.plugins。
三、Maven聚合与继承
项目目前划分成多个模块,Maven的聚合特性能把项目的各个模块聚合在一起构建,而继承特性可以帮助抽取各模块相同的依赖和插件等配置。聚合模块和继承关系的父模块中,packaging都必须是pom。
聚合
POM中,通过以下module元素的配置,会先解析聚合模块的POM,分析要构建的模块,计算一个反应堆构建顺序(Reactor Build Order),然后依次构建。
1 | <packaging>pom</packaging> |
继承
POM中,通过以下parent元素的配置,实现继承。artifactId无法继承。groupId、version、dependencies、dependenciesManagement、repositories、build等可以继承。例如SpringBoot的parent作用如下:
- jar包的版本管理
- 配置文件的过滤
- 常用插件管理
1 | <parent> |
Maven提供dependencyManagement元素,既让子模块继承到父模块的依赖配置,又能保证子模块依赖使用的灵活性。dependencyManagement元素下的声明不会引入实际的依赖,但是能约束dependencies下的依赖使用,这样可以省去version和scope,但是groupId和artifactId还必须保留。
例如SpringCloud的常用依赖如下:
1 | <dependencyManagement> |
另外,插件管理同样可以在父POM中使用pluginManagement元素来帮助管理插件。
Maven设计理念为“约定优于配置”,所有pom都继承于超级POM,文件路径:MAVEN_HOME/lib/maven-model-builder-x.x.x.jar中的org/apache/maven/model/pom-4.0.0.xml下。
四、Maven特性
Maven为了支持构建的灵活性,内置了几大特性:属性、Profile和资源过滤。
属性
在POM中可使用 “$ { 属性名称 }”来引用属性。
1、内置属性:
属性 | 含义 |
---|---|
basedir | 项目根目录 |
version | 项目版本 |
2、POM属性:
属性 | 含义 |
---|---|
project.build.sourceDirectory | 项目主源码目录 /src/main/src |
project.build.testSourceDirectory | 项目测试源码目录 /src/test/src |
project.build.directory | 项目构建输出目录 target/ |
project.outputDirectory | 项目主代码编译输出目录 target/classes |
project.testOutputDirectory | 项目测试代码编译输出目录 target/test-classes |
project.groupId | 项目的groupId |
project.artifactId | 项目的artifactId |
project.version | 项目的version |
project.build.finalName | 项目打包输出文件的名称 |
3、可通过properties元素自定义Maven属性。
4、Setting属性,引用settings.xml文件中XML元素的值,如settings.localRepository指向用户本地仓库的地址。
5、Java系统属性
6、环境变量属性,以env.开头,如env.JAVA_HOME。
资源过滤
比如在在src/main/resources目录下创建jdbc.properties文件:
1 | database.jdbc.driverClass = ${db.driver} |
POM默认为不启用资源过滤,可配置filtering为true启用过滤。
1 | <profiles> |
profile
激活方式:
1、命令行激活: mvn clean install -Pdev
2、settings文件显示激活,配置activeProfiles元素。如果是用户目录下,对本用户有效。如是全局目录,会对所有用户有效。
3、系统属性激活,通过activation元素,当系统属性存在与否、文件存在与否、操作系统环境、默认等情况时激活。
其他特性
maven本身并不是一个单元测试框架,Java的主流测试框架为JUnit和TestNG,Maven只是在构建到特定生命周期阶段时通过maven-surefire-plugin插件来执行JUnit或TestNG测试用例。
可通过配置插件来跳过测试。
可在target/surefire-reports目录生成测试报告。
可使用Jenkins(前身是Hudson)来持续集成。
可使用Cargo实现Web应用(war包)的自动化部署。
可使用maven-archetype-plugin插件快速生成项目骨架。
lifecycle、phase、goal
生成archetype
自己的插件
nexus使用
对比gradle
maven索引:
中央仓库带有索引文件以方便用户对其进行搜索,完整的索引文件大小约为1G,索引每周更新一次。
Cannot resolve plugin org.apache.maven.plugins:maven-war-plugin:2.2
因为网络原因造成下载的不完整,下载的jar包有问题,把之前本地仓库位置\org\apache\maven\plugins\maven-war-plugin\2.2下的文件删除,别删这个2.2,只删除里边内容就行,然后更新
mvn
mvn clean install -pl xxx_module -am -Dmaven.test.skip=true
mvn clean install -Ptest -pl com.ruoyi:xxx_module -Dmaven.test.skip=true -am -f ../../pom.xml
D:\Program Files\JetBrains\IntelliJ IDEA 2020.2.2\plugins\maven\lib\maven3\bin\mvn
多模块,jenkins单独打包子项目
clean install parent/child-module -am -amd -Pdev -Dmaven.test.skip=true
mvn安装
mvn install:install-file -DgroupId=xuggle -DartifactId=xuggle-xuggler -Dversion=5.4 -Dpackaging=jar -Dfile=D:\xuggle-xuggler-5.4.jar
gradle
gradle clean :xxx:build -Dprofile=snapshot -x test
清理本项目依赖的本地仓库的maven包,并重新下载
mvn dependency:purge-local-repository
lastUpdate文件为下载失败的包,可以直接删除