《Maven实战》阅读总结(四)聚合与继承
(七)聚合与继承软件设计人员往往会采用各种方式对软件划分模块,以得到更清晰的设计及更高的重用性。 聚合聚合项目,顾名思义,就是将多个项目聚合在一起。 |-parent <!-- 父工程是一个Maven项目 --> |-parent_POM <!-- 父工程拥有自己的POM文件,packaging元素值为pom,在modules中添加module元素实现项目聚合 --> |-sub1 <!-- 子工程通常位于父工程目录下,该目录通常与子工程artifactId相同,但不是必须 --> |-sub1_POM <!-- 父工程POM中module的值为子工程POM所在目录(相对目录,相对于父工程目录) --> |-sub2 <!-- --> |-sub2_POM <!-- --> 通常情况下,子工程位于父工程目录下,且子工程目录名与其artifactId相同,但实际情况由module的值所决定,即module值的路径能定位到子工程POM文件即可,对目录命名与布局没有绝对要求。 执行聚合项目声明周期时,Maveng会首先解析模块的POM、分析要构建的模块、并计算出一个反应堆构建顺序(Reactor Build Order),然后根据这个顺序依次构建各个模块。反应堆是所有模块组成的一个构建结构。 继承Maven的继承特性可以抽取重复的配置。在父POM中声明一些配置供子类POM继承,实现"一处声明,多处使用"。 1)继承声明在父工程POM文件中声明复用依赖或插件等配置,安装到本地仓库即可由其他子项目继续。 ... <parent> <groupId>...</groupId> <!-- 必须,声明父工程的groupId --> <artifactId>...</artifactId> <!-- 必须,声明父工程的artifactId --> <version>...</version> <!-- 必须,声明父工程的version --> <relativePath>...</relativePath> <!-- 可省略,默认为../pom.xml,声明父工程的POM文件所在路径 --> </parent> <artifactId>...<artifactId> <!-- 省略groupId和version,隐式继承父POM的groupId和version --> <name>...</name> ... 子项目构建时,Maven会根据relativePath检查父POM,如果找不到,再从仓库查找。 2)可继承的POM元素
3)依赖管理dependencyManagement 依赖管理配置,在该元素中声明的依赖不会被引入,而是起到约束并简化子项目依赖的作用,子项目会继承其声明的依赖配置,如version,scope。springboot项目的父工程应该是配置了该依赖管理配置,实现项目依赖无需填写版本号。 import依赖范围,只在dependencyManagement元素中生效,可以导入其他项目的dependencyManagement配置 <dependencyManagement> <dependencies> <dependency> <groupId>...</groupId> <artifactId>...</artifactId> <version>...</version> <type>pom</type> <scope>import</scope> </dependency> ... </dependencies> </dependencyManagement> 4)插件管理类似于dependencyManagement元素,pluginManagement元素用于管理插件,在该元素中配置的依赖不会造成实际的插件调用方式,可以理解为dependencyManagement 声明了插件依赖的配置,当其子类声明该插件依赖时,可复用该配置,起到约束和简化作用。 Ps:什么情况下可以用到依赖管理和插件管理,当一些依赖或插件依赖只有部分子模块需要时,应该由子模块自身去声明引入依赖并配置,而这些配置都是重复的,通过依赖管理和插件管理可以实现配置的复用,并且不会给其他模块引入不必要的依赖。 聚合和继承的关系
预定优于配置标准很重要,Web应用开发基于HTTP协议、Java屏蔽大部分操作系统差异,实现跨平台、所有语言都支持XML。
遵循约定虽然损失一定的灵活性,无法随意安排目录结构,但能减少配置,帮助用户遵守标准。 Maven可自定义源码目录 <build> <sourceDirectory>...</sourceDirectory> <!-- 不推荐自定义源码目录,提高交流成本 --> </build> 关于超级POM <!-- 主输出目录 --> <directory>${project.basedir}/target</directory> <!-- 主代码输出目录 --> <outputDirectory>${project.build.directory}/classes</outputDirectory> <!-- 最终构件的名称格式 --> <finalName>${project.artifactId}-${project.version}</finalName> <!-- 测试代码输出目录 --> <testOutputDirectory>${project.build.directory}/test-classes</testOutputDirectory> <!-- 主源码目录 --> <sourceDirectory>${project.basedir}/src/main/java</sourceDirectory> <!-- 脚本源码目录 --> <scriptSourceDirectory>${project.basedir}/src/main/scripts</scriptSourceDirectory> <!-- 测试源码目录 --> <testSourceDirectory>${project.basedir}/src/test/java</testSourceDirectory> <!-- 主资源目录 --> <resources> <resource> <directory>${project.basedir}/src/main/resources</directory> </resource> </resources> <!-- 测试资源目录 --> <testResources> <testResource> <directory>${project.basedir}/src/test/resources</directory> </testResource> </testResources> 最后,超级POM通过插件管理为核心插件设定了版本,防止由于插件版本的变化而造成构建不稳定。 反应堆在一个多模块的Maven项目中,反应堆(Reactor)是指所有模块组成的一个构建结构。 1)反应堆的构建顺序Maven按序读取POM,如果该POM没有依赖模块,则构建该模块,否则就先构建其依赖模块,如果该依赖还依赖于其他依赖,则进一步构建依赖的依赖。 2)裁剪反应堆一般来说,用户会选择构建整个项目或选择构建单个模块。
在开发过程中,灵活应用上述4个参数,可以帮助我们跳过无须构建的模块,加速构建。当项目庞大、模块特别多时,这种效果就会异常明显。 (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |