9.4.6. 依赖管理

当你在你的超级复杂的企业中采用Maven之后,你有了两百多个相互关联的Maven项目,你开始想知道是否有一个更好的方法来处理依赖版本。如果每一个使用如MySQL数据库驱动依赖的项目都需要独立的列出该依赖的版本,在你需要升级到一个新版本的时候你就会遇到问题。由于这些版本号分散在你的项目树中,你需要手工的编写每一个引用该依赖的pom.xml,确保每个地方的版本号都更改了。即使使用了findxargs,和,awk,你仍然有漏掉一个POM的风险。

幸运的是,Maven在dependencyManagement元素中为你提供了一种方式来统一依赖版本号。你经常会在一个组织或者项目的最顶层的父POM中看到dependencyManagement元素。使用pom.xml中的dependencyManagement元素能让你在子项目中引用一个依赖而不用显式的列出版本号。Maven会沿着父子层次向上走,直到找到一个拥有dependencyManagement元素的项目,然后它就会使用在这个dependencyManagement元素中指定的版本号。

例如,如果你有一大组项目使用MySQL Java connector版本5.1.2,你可以在你的多模块项目的顶层POM中定义如下的dependencyManagement元素。

Example 9.9. 在一个顶层POM中定义依赖版本

<project>
  <modelVersion>4.0.0</modelVersion>
  <groupId>org.sonatype.mavenbook</groupId>
  <artifactId>a-parent</artifactId>
  <version>1.0.0</version>
  ...
  <dependencyManagement>
    <dependencies>
      <dependency>
        <groupId>mysql</groupId>
        <artifactId>mysql-connector-java</artifactId>
        <version>5.1.2</version>
      </dependency>
      ...
    <dependencies>
  </dependencyManagement>

然后,在子项目中,你可以使用如下的依赖XML添加一个对MySQL Java Connector的依赖:

<project>
  <modelVersion>4.0.0</modelVersion>
  <parent>
    <groupId>org.sonatype.mavenbook</groupId>
    <artifactId>a-parent</artifactId>
    <version>1.0.0</version>
  </parent>
  <artifactId>project-a</artifactId>
  ...
  <dependencies>
    <dependency>
      <groupId>mysql</groupId>
      <artifactId>mysql-connector-java</artifactId>
    </dependency>
  </dependencies>
</project>

你应该注意到该子项目没有显式的列出mysql-connector-java依赖的版本。由于这个依赖在顶层POMdependencyManagement元素中定义了,该版本号就会传播到所有子项目的mysql-connector-java依赖中。注意如果子项目定义了一个版本,它将覆盖顶层POMdependencyManagement元素中的版本。那就是:只有在子项目没有直接声明一个版本的时候,dependencyManagement定义的版本才会被使用。

顶层POM中的依赖管理与在一个广泛共享的父POM中定义一个依赖是不同的。对初学者来说,所有依赖都会被继承。如果mysql-connector-java在顶层父项目中被作为一个依赖列出,这个层次中的所有项目都将引用该依赖。为了不添加一些不必要的依赖,使用dependencyManagement能让你统一并集中化依赖版本的管理,而不用添加那些会被所有子项目继承的依赖。换句话说,dependencyManagement元素和一个环境变量一样,能让你在一个项目下面的任何地方声明一个依赖而不用指定一个版本号。