一、父工程与子模块间的继承依赖
许多项目都采用了模块化的方式,即一个主工程下可能包含多个模块。
parent
|—-pom.xml
|—-module1
|—-pom.xml
|—-module2
|—-pom.xml
|—-module3
|—-pom.xml
|—-module4
|—-pom.xml
试想一下,如果我们不加考虑的在各自模块的pom.xml中加入依赖会出现什么情况呢?
各个模块出现引入一个jar的各种版本,即使处理冲突后你会发现每个模块的pom.xml中存在大量的版本号,这就意味着如果你在修改项目中jar的版本时需要修改每个模块中pom.xml的版本号,这是十分不合理的。maven设计时也考虑到这个问题,所以在面对这个问题时,maven采用了两种继承的方式来解决这个问题。
方式1:
父工程的pom.xml
<dependencyManagement>
<dependencies>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.20</version>
</dependency>
<dependency>
<groupId>commons-logging</groupId>
<artifactId>commons-logging</artifactId>
<version>1.2</version>
</dependency>
</dependencies>
</dependencyManagement>
module1的pom.xml
<dependencies>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
</dependency>
<dependency>
<groupId>commons-logging</groupId>
<artifactId>commons-logging</artifactId>
</dependency>
</dependencies>
其他模块类同module1。这样一来,子模块无需引入版本号就能够实现依赖,当我们需要修改某个jar的版本时,只需要在父工程中修改即可。
方式2:
父工程的pom.xml
<dependencies>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.20</version>
</dependency>
<dependency>
<groupId>commons-logging</groupId>
<artifactId>commons-logging</artifactId>
<version>1.2</version>
</dependency>
</dependencies>
这种方式下子模块已经继承了父工程下<dependencies></dependencies>
中所有的jar。
方式1和方式2对比:
在方式2下,子模块对父工程的项目依赖是全部继承的;而在方式1下,父工程只是在<dependencyManagement><dependencies></dependencies></dependencyManagement>
声明了子模块可以引入这些依赖,但是子模块必须显示添加不含版本的<dependency></dependency>
才会引入。所以方式1在继承依赖上更加地灵活。
二、工程与工程间的继承依赖
在大型项目中,可能已经写好了很多中间件工程,你需要这些中间件时只需要在maven中继承一下即可,那么maven具体是如何处理这种继承的呢?
1.单继承
工程的pom.xml
<parent>
<groupId>xxx</groupId>
<artifactId>xxx</artifactId>
<version>x.x.x</version>
</parent>
<artifactId>xxx</artifactId>
<version>1.0-SNAPSHOT</version>
...
<dependencies>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
</dependency>
<dependency>
<groupId>commons-logging</groupId>
<artifactId>commons-logging</artifactId>
</dependency>
</dependencies>
在<parent></parent>
中是工程依赖的项目,该项目中包含了mysql和commons-logging的依赖,所以在<dependencies></dependencies>
可以直接加入它们的依赖。
然而,这种方式问题还是比较明显的,那就是如果我们需要继承多个项目时就无法处理了,maven是支持多继承的工程依赖的。
2.多继承依赖
<!--
<parent>
<groupId>xxx</groupId>
<artifactId>xxx</artifactId>
<version>x.x.x</version>
</parent>
-->
<groupId>xxx</groupId>
<artifactId>xxx</artifactId>
<version>1.0-SNAPSHOT</version>
...
<dependencies>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
</dependency>
<dependency>
<groupId>commons-logging</groupId>
<artifactId>commons-logging</artifactId>
</dependency>
</dependencies>
<dependencyManagement>
<!--maven多继承方式-->
<dependency>
<groupId>xxx</groupId>
<artifactId>xxx</artifactId>
<version>xxx</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencyManagement>
这时就不需要<parent></parent>
了,而在<dependencyManagement><dependencies></dependencies></dependencyManagement>
加入对其他项目的依赖即可,这样无论是当前工程还是子模块都是可以显示地引入该项目的依赖的。这里需要特别注意一下<type>pom</type>
,pom对应的是你引入的工程的<packaging>pom</packaging>
。