兴宁网站建设,联享品牌网站建设公司,个人博客搭建wordpress,青海高端网站建设多少钱该文章为maven系列学习的第三篇#xff0c;也是最后一篇 第一篇快速入口#xff1a;从0到0.1学习 maven(一#xff1a;概述及简单入门) 第二篇快速入口#xff1a;从0到0.1学习 maven(二#xff1a;坐标、依赖和仓库) 文章目录啥子叫生命周期生命周期详解clean生命周期def…该文章为maven系列学习的第三篇也是最后一篇 第一篇快速入口从0到0.1学习 maven(一概述及简单入门) 第二篇快速入口从0到0.1学习 maven(二坐标、依赖和仓库) 文章目录啥子叫生命周期生命周期详解clean生命周期default生命周期site生命周期插件插件配置插件解析聚合继承可继承的元素依赖管理插件管理小结反应堆裁剪反应堆啥子叫生命周期
构建步骤包括项目清理初始化编译测试打包集成测试验证部署等等。maven将这些过程进行了抽象与统一映射到了生命周期上。 可以将maven的生命周期理解成设计模式中的模板方法。父类定义整体结构子类进行具体方法的实现和重写。在控制整体结构的同时也增加了可拓展性。maven没有对这些步骤提供实现但是提供了默认绑定的插件因此实际上每个步骤都是通过插件完成的。
生命周期详解
实际上maven中的生命周期分成了三套分别为cleandefault与site分别对应着 清理构建与建立项目站点。每套生命周期都对应着一些有序的阶段。等下会详细介绍。三套生命周期本身是相互独立的也就是调用clean不会影响到site。
clean生命周期
阶段1pre-clean: 执行清理前需要完成的工作 阶段2clean清理上一次构建生成的文件 阶段3post-clean执行一些清理后需要完成的工作 阶段间是有序的因此若想调用post-clean会按preclean-clean-postclean的顺序执行。
default生命周期
在default周期中定义了真正构建时需要的步骤。官方介绍可以参考https://maven.apache.org/guides/introduction/introduction-to-the-lifecycle.html
validate验证项目是否正确所有需要的信息是否都可用initialize初始化例如属性的设置、 目录的创建等generate-sourcesprocess-sources处理项目主资源文件一般是在src/main/resources中完成变量替换等再复制到项目输出的主classpath目录中。generate-resourcesproess-resourcescompile编译源代码一般是在src/main/java目录下process-classesgenerate-test-sourcesprocess-test-sources处理测试资源文件。一般是在src/test/resources目录下将该目录下的java文件编译输出到测试的classpath目录中。generate-test-resourcesprocess-test-resourcestest-compile编译项目的测试代码。一般在src/test/java目录下。编译好后输出到测试的classpath目录中。process-test-classestest用单元测试框架来测试编译后的源代码测试代码不会打包或者部署。prepare-packagepackage用指定的后缀格式将编译后的代码进行打包pre-integration-testintegration-testpost-integration-testverifyinstall将package安装到本机的仓库中以供其他依赖它的项目使用deploy将最终的package复制到远程仓库中以供其他开发者与项目共享
site生命周期
该周期的主要作用为建立和发布项目站点。根据pom中包含的信息自动生成站点。
pre-site完成一些生成项目站点之前需要的工作site生成项目站点文档post-site完成一些生成项目站点之后的工作site-deploy将生成的项目站点发布到服务器上。
插件
首先介绍一下插件目标可以将一个小功能点理解成一个目标。前面提到核心功能都是通过插件的形式来实现的但是针对一个功能点就开发一个插件显然会有很多冗余代码。因此一个插件可能会包含多个插件目标。
生命周期会与插件相互绑定例如对于A过程 插件B可以完成该任务因此将AB进行绑定。如果某过程没有绑定插件那该过程就不会有实际行为。 为了让用户几乎不用配置就可以构建maven项目maven会对主要的生命周期阶段进行内置的插件绑定。 另外一个插件也可以绑定多个阶段例如clean生命周期的三个阶段都绑定在了maven-clean-plugin:clean插件上。
除了内置的绑定之外用户也可以对阶段使用的插件进行自定义的绑定。
举一个自定义绑定插件的例子
buildpluginsplugingroupIdorg.apache.maven.plugins/groupIdartifactIdmaven-source-plugin/artifactIdversion2.2.1/versionexecutionsexecutionidattach-sources/idphaseverify/phasegoalsgoaljar/goal/goals/execution/executions/plugin/plugins
/build可以看到在execution元素下指定了phase阶段和goal目标。
尝试删除phase阶段再次执行mvn verfify执行依然成功。因为很多插件的目标在编写的时候已经默认绑定了阶段。可以通过mvn help:describe -Dpluginxxxxx -Ddetail来查看具体信息
运行mvn help:describe -Dpluginorg.apache.maven.plugins:maven-source-plugin:2.2.1 -Ddetail看一下我们刚刚用的包的细节。 第五行Bound to phase: package 指明了他绑定的默认生命周期阶段时package。
ps: 如果不加版本号则自动获取最新的版本。加了detail是为了更详细的信息。如果仅仅想知道某个目标的信息可以使用goal参数。
插件配置
命令行配置 maven沿用了java的命令行传参模式即“-D” 例如上述例子中 -Dpluginxxx就表示着传递 名为plugin值为xxx的参数。
POM中插件全局配置 对于很少或不会改变的参数直接写死在pom文件中。 直接在version下面加一个configuration的子标签
configurationsource1.5/sourcetarget1.5/target
/configurationPOM中配置任务参数 还可以为某个插件任务配置特定的参数
configurationtasksechoI am a task/echo/tasks
/configuration插件解析
首先需要了解一个插件前缀的概念。我们刚刚使用了mvn help:describe实际上是maven-help-plugin插件的describe目标。这里help就是插件前缀其结构是groupIdartifactId。复习一下依赖仓库的路径groupId/artifactId/maven-metadata.xml插件仓库的元数据是在groupId/maven-metadata.xml下的。
插件像构件一样以坐标的形式存储在maven仓库中。 插件仓库的子元素配置和依赖仓库完全相同。 repositoriesrepositoryidcentral/idnameCentral Repository/nameurlhttps://repo.maven.apache.org/maven2/urllayoutdefault/layoutsnapshotsenabledfalse/enabled/snapshots/repository/repositories如果是maven的官方插件groupIdorg.apache.maven.plugins则可以省略groupId配置。
对于核心插件maven为它们在超级pom所有maven项目的父pom中预先设定了版本。因此核心插件可以不用指定版本。
对于非核心插件类似于仓库的版本解析插件也有元数据文件。maven遍历本地与远程插件仓库找到lastest和release。maven2会使用latestmaven3会使用release。
聚合
实际项目中可能是会由多个项目组合起来的需要对每个项目进行打包构建。如果每次都一个一个地去模块对应的目录下构建那是相当麻烦。因此聚合也叫多模块 就是在一个目录可以构建项目中的所有包。
首先需要创建出一个额外的模块并写pom文件
?xml version1.0 encodingUTF-8?
project xmlnshttp://maven.apache.org/POM/4.0.0 xmlns:xsihttp://www.w3.org/2001/XMLSchema-instance xsi:schemaLocationhttp://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsdmodelVersion4.0.0/modelVersiongroupIdcom.company.sc/groupIdartifactIddemo/artifactIdversion1.0.0-SNAPSHOT/versionpackagingpom/packagingnamea_practise_demo/namedescription用于练习聚合的项目/descriptionmodulesmodulemodule_name_1/modulemodulemodule_name_2/modulemodulemodule-name-3/module/modules
/project它与普通的模块有三处不同
packaging的值为pom这标志着该模块为聚合模块。对其需要打包的子模块都遵照各模块的packaging类型。多了一层modules标记着该聚合模块包含哪些模块。值得注意的是这里module子标签实际上不是真正的模块名而是模块的目录名。因此如果这个聚合模块不是其他模块的父文件夹的话需要将module元素的内容改成能指向正确模块的目录。实际上该聚合模块只会包含一个pom.xml文件不会有test或java目录和代码。它仅仅是帮助构建的工具并没有实际的内容。
继承
在maven世界里也有继承这个概念。像聚合一样需要单独抽出一个目录编写父pom以完成“一处声明多处使用”的目的。
?xml version1.0 encodingUTF-8?
project xmlnshttp://maven.apache.org/POM/4.0.0 xmlns:xsihttp://www.w3.org/2001/XMLSchema-instance xsi:schemaLocationhttp://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsdmodelVersion4.0.0/modelVersiongroupIdcom.company.sc/groupIdartifactIddemo-parent/artifactIdversion1.0.0-SNAPSHOT/versionpackagingpom/packagingnamea_practise_demo/name
/project它与聚合有两点相同
除了pom之外没有其他目录packaging使用的也是pom
继承父类的子模块需要加入如下内容
parentgroupIdcom.company.sc/groupIdartifactIddemo-parent/artifactIdversion1.0.0-SNAPSHOT/versionrelativePath../dir1/dir2/pom.xml/relativePath
/parentgroupId, artifactId, version 是定义坐标系的三个最基本的元素是必须的。relativePath表示父pom的相对路径默认值是…/pom.xml也就是maven默认父pom在上一层目录下。
另外如果有聚合模块的话该继承模块也需要被添加到modules标签下。
可继承的元素
groupIdversiondescriptionorganizationinceptionYear项目的创建年份url项目的url地址developerscontributorsdistributionManagement项目的部署配置issueManagement项目的issue信息ciManagement项目的持续集成系统信息scm项目的版本控制系统信息mailingListsproperties自定义maven属性dependencies项目的依赖配置dependencymanagement项目的依赖管理配置repositories项目的仓库配置build包括项目的源码目录配置、输出目录配置、插件配置等reporting包括项目的报告输出目录配置报告插件配置等
依赖管理
父类的依赖可以被子类继承但不一定所有的父类依赖都会被每个子类使用。这里maven提供了dependencyManagement元素能让子模块继承到父模块的依赖配置又能保证灵活性。因为dm元素下的依赖声明不会引入实际的依赖但却能控制依赖。比如可以在父pom中声明依赖的groupId, artifactId, versionscope子模块中就只需要groupId, artifactId其他都可以从父类中继承。
依赖范围import只在dependencyManagement中才有效果。它的作用是将某pom中dm标签下的配置导入并合并到当前pom的dm元素中。假设另外一个模块想要导入我们前面的父类pom可以通过以下配置。
dependencyManagementdependenciesdependencygroupIdcom.company.sc/groupIdartifactIddemo-parent/artifactIdversion1.0.0-SNAPSHOT/versiontypepom/typescopeimport/scope/dependency/dependencies
/dependencyManagement一般import都会指向打包类型为pom的模块因此type元素的值为pom。
插件管理
类似于刚刚的依赖管理插件相应地也可以使用pluginManagement进行管理在父pom中配置plugin元素当子pom中继承并配置了对应地groupId和artifactIdpm中的配置才会生效。
小结
对于聚合模块它知道有哪些被聚合的模块但是被聚合的模块不知道它。对于继承模块继承该模块的子模块知道他但是他不知道都有谁继承了他。两个关系刚好相反但是配置的时候packaging都必须是pom。在实际项目中一个pom可能又当聚合pom又当父pom。
反应堆
反应堆指的是所有的模块形成的一个构建结构。拿以下模块为例子该部分从demo的pom中提取。
modulesmodulemodule_name_child_1/modulemodulemodule_name_father/modulemodulemodule_name_no_father/module
/modules反应堆的构建顺序与声明顺序不一定一致这个要取决于聚合与依赖关系。实际的构建顺序应为 demo-module_name_father-module_name_child_1-module_name_no_father demo是聚合模块的起点肯定是第一个构建的然后按照顺序读取到了module_name_child_1检查到它依赖着module_name_father于是先去构建module_name_father。构建好了之后再构建module_name_father。接着继续按顺序构建到module_name_no_father。一般来讲依赖关系会将反应堆构建为有向无环图如果有环在构建时maven就会报错。
裁剪反应堆
如果想构建反应堆中的某些模块可以使用mvn -h
-am –also-make同时构建所列模块的依赖模块-amd-also-make-dependens同时构建 依赖于所列模块的模块-pl–projects args 构建指定的模块用逗号做分隔符-rf-resume-fromargs 从指定的模块构建反应堆
举个例子假设a依赖于b和c如果用-am a的话就会同时构建a b c。如果用-amd b的话就会构建 a b。假设之前的构建顺序是 a b c d那-rf c 就会构建c和d