第8章 聚合和继承
聚合
用户可以通过在一个打包方式为pom(<packaging>pom</packaging>)的maven项目中声明任意数量的module元素来实现模块的聚合。每个module的值都是一个当前pom文件的相对目录。
如果希望将当前构件安装到本地仓库,打包方式应该是<packaging>jar</packaging>,虽然默认的就是jar。
聚合的特性允许我们一次命令同时构建多个模块(或工程),它的目的是为了方便我们构建多个模块或工程的。
继承
pom继承特性是为了帮助消除多个模块之间的重复配置,因此它本身不包含除pom之外的项目文件,也就不需要src/main/java,src/main/resources等文件夹,直接地说就是只需要pom文件即可。
继承特性使用parent元素来申明当前模块的父模块,而子模块的pom文件可以继承父pom的那些元素包括:groupid,version,description,organization...propeties,dependencies,dependencymanagemenet,,repositories,build,reporting等。
如果两个模块它们之间有很多相同的dependency,我们可以将这些依赖都放置在父pom文件中,而子pom就不需要再重复配置了。但是这样做带来一个问题是,如果后面的项目过程中,你又增加了一个新的子模块,而这个子模块不一定也会依赖父模块的构件,这样就不是很合理了。庆幸的是,maven提供了一个更加灵活的实现继承依赖的元素dependencymanagement,它既能实现子模块继承到父模块的依赖配置,又能保证子模块依赖使用的灵活性。它的实现方式是在父pom文件中增加元素dependencymanagement:
- <dependencyManagement>
- <dependencies>
- <dependency>
- <groupId>...</groupId>
- <artifactId>...</artifactId>
- <version>...</version>
- </dependency>
- <dependency>
- <groupId>...</groupId>
- <artifactId>...</artifactId>
- <version>...</version>
- </dependency>
- ...
- </dependencies>
- </dependencyManagement>
它的灵活之处在于,dependencymanagement既不会为父模块引入依赖,也不会为子模块引入依赖,只有在子模块pom中的dependency里再度声明依赖,指定的构件才会被真正依赖。那看起来似乎依赖管理并没有为我们减少太多的配置,但是一个很重要的特性是,所有version都只需要在父pom中声明,子pom只需要申明构件坐标的groupId和artifactId(当然要和父pom中的dependencymanagement申明的这两个坐标保持一致),这样做的好处是巨大的,所有版本的调整都只需要在父pom中设置,子模块完全不需要一个一个地修改,也极大地避免了版本依赖冲突地问题。
聚合和继承的关系
二者的目的完全不同,聚合是为了方便快速构建项目,继承则是为了消除重复配置。 对于聚合模块,它知道又那些被聚合的模块(“目录”应该更准确一些,模块让人感觉是指构件,目录只是硬盘上的一个项目文件夹),但是被聚合的模块并不知道这个聚合模块的存在。对于继承关系的父pom来说,它不知道有那些子模块继承与它,但这些子模块都知道它的存在。
共同之处,表现上,聚合和继承pom文件打包方式都是pom,而他们作为父模块都没有什么实际的内容。
在现有的项目中,往往一个pom既是聚合pom,又是继承pom。书的那个例子实在是不错,可惜太长了,就不拷贝了。
“约定大于配置”-maven最核心的设计理念之一。