最近重新读了一下《Maven实战》,记录一下一直被我忽略的聚合
和继承
的关系。
聚合
首先,一个模块有一个pom(Project object Model)文件。当一个项目比较大的时候,按一定规则划分成不同的模块是一个比较好的方式。这时候管理一个项目,如果每个模块座位一个项目,那么打包编译的时候需要到每一个模块下去执行mvn命令,太麻烦了。于是,有个继承模块。
继承模块是一个空模块,只有pom文件,没有src、resource之类的目录结构。在pom文件中,用<modules>
和<module>
标签指定要管理的子模块。另外,<packaging>
标签必须指定为pom。
- e.g:
<packaging>pom</packaging>
<modules>
<module>account-model</module>
<module>account-service</module>
<module>account-task</module>
</modules>
以上情况适用于聚合模块处于目录顶层,子模块是聚合模块的子目录的情况。如果子模块和聚合模块是平行的目录关系,那么应该根据实际路径来写。
- e.g:
<packaging>pom</packaging>
<modules>
<module>../account-model</module>
<module>../account-service</module>
<module>../account-task</module>
</modules>
这样,一个聚合模块就做好了,打包编译只需要在聚合模块下执行命令即可。
继承
当多个子模块需要的依赖相同和重复时,就推荐使用继承来消除重复了。声明一个可被继承的父模块,也是要把<packaging>
标签指定为pom。子模块中指定父模块的坐标
- e.g:
<parent>
<groupId>com.demo</groupId>
<artifactId>account-parent</artifactId>
<version>0.0.1-SNAPSHOT</version>
</parent>
父模块中可以声明<dependencyManagement>
,这个标签不会真的引入依赖,只是定义公用的坐标,子模块继承后仍然需要指定<groupId>
和<artifactId>
,可省略<version>
标签。这么做看起来没节省多少工作,但是能有效管理依赖,避免项目出现不同版本的依赖问题。
如果父模块和子模块是平行目录,那么子模块中需要指定父模块的地址。
- e.g:
<parent>
<groupId>com.demo</groupId>
<artifactId>account-parent</artifactId>
<version>0.0.1-SNAPSHOT</version>
<relativePath>../account-parent/pom.xml</relativePath>
</parent>
Maven默认是从上级目录解析父模块,所以如果子模块在父模块的下级目录,可省略<relativePath>
。
一般推荐顶层目录中声明模块,它即是聚合模块,也是可被继承的父模块
import依赖范围
一直不知道import依赖范围的作用,这里记录一下。
这个依赖范围,只在<dependencyManagement>
元素下才有效。
它的作用是指向一个pom,将目标pom中的<dependencyManagement>
配置导入并且合并到当前pom的<dependencyManagement>
中。
也就是说,一个新模块的<dependencyManagement>
中,有一堆配置在其他某个pom中的<dependencyManagement>
里配置过了,此处就不必再复制粘贴一遍,可以直接使用import引入进来。
- e.g:有一个现成的a-parent模块配置了
<dependencyManagement>
,在b-parent模块中就不必拷贝大段配置了
<dependencyManagement>
<dependencies>
<dependency>
<groupId>com.demo</groupId>
<artifactId>a-parent</artifactId>
<version>0.0.1-SNAPSHOT</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>