在Java平台大型项目的构建中,常常需要在多个子项目间统一依赖库的设置信息,包括依赖那些库?库的版本是什么?等等。为解决这个问题, Maven 中提供了 DependencyManagement 选项。
概念和形式 为了说明 DependencyManagement 的用法,我使用开源项目 ServiceComb 的BMI示例程序作为案例。
在 bmi 的样例的父项目 pom.xml 文件如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 <project xmlns ="http://maven.apache.org/POM/4.0.0" xmlns:xsi ="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation ="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd" > <modelVersion > 4.0.0</modelVersion > <groupId > org.apache.servicecomb.samples</groupId > <artifactId > bmi</artifactId > <name > Java Chassis::Samples::BMI</name > <version > 1.3.0-SNAPSHOT</version > <packaging > pom</packaging > <modules > <module > calculator</module > <module > webapp</module > </modules > <description > Quick Start Demo for Using ServiceComb Java Chassis</description > <properties > <project.build.sourceEncoding > UTF-8</project.build.sourceEncoding > <project.reporting.outputEncoding > UTF-8</project.reporting.outputEncoding > <java.version > 1.8</java.version > <java-chassis.version > #123;project.version}</java-chassis.version > <spring-boot-1.version > 1.5.14.RELEASE</spring-boot-1.version > </properties > <dependencyManagement > <dependencies > <dependency > <groupId > org.apache.servicecomb</groupId > <artifactId > java-chassis-dependencies</artifactId > <version > #123;java-chassis.version}</version > <type > pom</type > <scope > import</scope > </dependency > <dependency > <groupId > org.springframework.boot</groupId > <artifactId > spring-boot-dependencies</artifactId > <version > #123;spring-boot-1.version}</version > <type > pom</type > <scope > import</scope > </dependency > </dependencies > </dependencyManagement > <dependencies > <dependency > <groupId > org.hibernate.validator</groupId > <artifactId > hibernate-validator</artifactId > </dependency > <dependency > <groupId > javax.validation</groupId > <artifactId > validation-api</artifactId > </dependency > </dependencies > <build > <plugins > <plugin > <groupId > org.apache.rat</groupId > <artifactId > apache-rat-plugin</artifactId > <version > 0.13</version > <configuration > <excludes > <exclude > .travis.yml</exclude > <exclude > **/*.md</exclude > <exclude > **/target/*</exclude > <exculde > **/resources/ssl/**</exculde > <exclude > **/*.proto</exclude > <exclude > **/*.idl</exclude > </excludes > </configuration > </plugin > </plugins > </build > </project >
可以看到,在26行和43行之间定义了 DependencyManagement,该定义指名了当前项目将继承来至 artifactId 为 java-chassis-dependencies 和 spring-boot-dependencies 的项目的依赖。
我们再打开 java-chassis-dependencies 依赖,可以看到该项目主要包含一个 pom.xml 文件,里面定义了众多的依赖性及其版本。如下(节选):
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 <properties > <apache-commons.version > 3.7</apache-commons.version > <archaius.version > 0.7.6</archaius.version > ... <main.basedir > #123;basedir}/../..</main.basedir > </properties > <dependencyManagement > <dependencies > <dependency > <groupId > ch.qos.logback</groupId > <artifactId > logback-classic</artifactId > <version > #123;logback.version}</version > </dependency > <dependency > <groupId > ch.qos.logback</groupId > <artifactId > logback-core</artifactId > <version > #123;logback.version}</version > </dependency > <dependency > <groupId > com.101tec</groupId > <artifactId > zkclient</artifactId > <version > #123;tec-zkclient.version}</version > </dependency > ... </dependencies > </dependencyManagement >
通过这个方式, BMI项目和其子项目只需要生命依赖库,系统就会使用在 dependencyManagement 中确定的版本。使得在多个项目中维护相同的依赖库及版本变得容易。
如果在子项目中需要定义某个特定的版本,直接在子项目中重复定义即可。
与直接在子项目中使用 dependencies 的区别 dependencies 即使在子项目中不写该依赖项,那么子项目仍然会从父项目中继承该依赖项
ependencyManagement里只是声明依赖,并不实现引入,因此子项目需要显示的声明需要用的依赖。如果不在子项目中声明依赖,是不会从父项目中继承下来的;只有在子项目中写了该依赖项,并且没有指定具体版本,才会从父项目中继承该项,并且version和scope都读取自父pom ;