背景:最近在学习maven的多模块构建过程中看到DependencyManagement选项,对这个选项的使用做个记录!

区别与联系

这里介绍一个在父项目中的根结点中声明dependencyManagement和dependencies的区别

dependencyManagement使用

dependencyManagement只会影响现有依赖的配置,但不会引入依赖。

例如我们可以在父模块中配置如下:

<dependencyManagement>
<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactid>junit</artifactId>
<version>4.8.2</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>log4j</groupId>
<artifactid>log4j</artifactId>
<version>1.2.16</version>
</dependency>
</dependencies>
</dependencyManagement>

这段配置不会给任何子模块引入依赖,但如果某个子模块需要使用JUnit和Log4j的时候,我们就可以简化依赖配置成这样:

 <dependency>
<groupId>junit</groupId>
<artifactid>junit</artifactId>
</dependency>
<dependency>
<groupId>log4j</groupId>
<artifactid>log4j</artifactId>
</dependency>

现在只需要groupId和artifactId,其它元素如version和scope都能通过继承父POM的dependencyManagement得到,如果有依赖配置了exclusions,那节省的代码就更加可观。但重点不在这,重点在于现在能够保证所有模块使用的JUnit和Log4j依赖配置是一致的。而且子模块仍然可以按需引入依赖,如果我不配置dependency,父模块中dependencyManagement下的spring-aop依赖不会对我产生任何影响。

也许你已经意识到了,在多模块Maven项目中,dependencyManagement几乎是必不可少的,因为只有它是才能够有效地帮我们维护依赖一致性。

dependencies

相对于dependencyManagement,所有声明在dependencies里的依赖都会自动引入,并默认被所有的子项目继承。

classifier

如果你要发布同样的代码,但是由于技术原因需要生成两个单独的构件,你就要使用一个分类器(classifier)。例如,如果你想要构建两个单独的构件成JAR,一个使用Java 1.4 编译器,另一个使用Java 6 编译器,你就可以使用分类器
来生成两个单独的JAR构件,它们有同样的groupId:artifactId:version组合。如果你的项目使用本地扩展类库,你可以使用分类器为每一个目标平台生成一个构件。分类器常用于打包构件的源码,JavaDoc 或者二进制集合。

dependencyManagement精进

我们知道Maven的继承和Java的继承一样,是无法实现多重继承的,如果10个、20个甚至更多模块继承自同一个模块,那么按照我们之前的做法,这个父模块的dependencyManagement会包含大量的依赖。

如果你想把这些依赖分类以更清晰的管理,那就不可能了,import scope依赖能解决这个问题。你可以把dependencyManagement放到单独的专门用来管理依赖的POM中,然后在需要使用依赖的模块中通过import scope依赖,就可以引入dependencyManagement。

例如可以写这样一个用于依赖管理的POM:

<project>
<modelVersion>4.0.0</modelVersion>
<groupId>com.juvenxu.sample</groupId>
<artifactId>sample-dependency-infrastructure</artifactId>
<packaging>pom</packaging>
<version>1.0-SNAPSHOT</version>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactid>junit</artifactId>
<version>4.8.2</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>log4j</groupId>
<artifactid>log4j</artifactId>
<version>1.2.16</version>
</dependency>
</dependencies>
</dependencyManagement>
</project>

然后我就可以通过非继承的方式来引入这段依赖管理配置:

<dependencyManagement>
<dependencies>
<dependency>
<groupId>com.juvenxu.sample</groupId>
<artifactid>sample-dependency-infrastructure</artifactId>
<version>1.0-SNAPSHOT</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement> <dependency>
<groupId>junit</groupId>
<artifactid>junit</artifactId>
</dependency>
<dependency>
<groupId>log4j</groupId>
<artifactid>log4j</artifactId>
</dependency>

这样,父模块的POM就会非常干净,由专门的packaging为pom的POM来管理依赖,也契合的面向对象设计中的单一职责原则。此外,我们还能够创建多个这样的依赖管理POM,以更细化的方式管理依赖。

这种做法与面向对象设计中使用组合而非继承也有点相似的味道。

plugins和pluginmanagement的区别

pluginmanagement标签一般用在父pom中,子元素可以包含plugins插件,比如

<pluginManagement>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-source-plugin</artifactId>
<version>2.1</version>
<configuration>
<attach>true</attach>
</configuration>
<executions>
<execution>
<phase>compile</phase>
<goals>
<goal>jar</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</pluginManagement>

然后,在子pom文件中就可以这样使用:

<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-source-plugin</artifactId>
</plugin>
</plugins>

省去了版本、配置等信息,只需指定groupId和artifactId即可。

但是在父pom中,如果使用这个标签来包裹plugins插件,当在此项目根目录运行对应的mvn命令时,如果在子pom中没有直接像上面再次引用这个plugin,那么不会触发这个plugin插件,只有在子pom中再次引用了之后,才会在对应的子项目路径下触发这个plugin.

plugins和pluginManagement标签都需要在build标签中。

关于插件pluginManagement,Maven并没有提供与import scope依赖类似的方式管理,那我们只能借助继承关系,不过好在一般来说插件配置的数量远没有依赖配置那么多,因此这也不是一个问题。

(转)Maven中的DependencyManagement和pluginmanagement的更多相关文章

  1. 【maven】Maven中的dependencyManagement

    dependencyManagement使用简介 Maven中的dependencyManagement元素提供了一种管理依赖版本号的方式.在dependencyManagement元素中声明所依赖的 ...

  2. Maven中的DependencyManagement和Dependencies

    Maven 使用dependencyManagement 元素来提供了一种管理依赖版本号的方式.通常会在一个组织或者项目的最顶层的父POM 中看到dependencyManagement 元素.使用p ...

  3. Maven中的dependencyManagement 意义

    1.在Maven中dependencyManagement的作用其实相当于一个对所依赖jar包进行版本管理的管理器. 2.pom.xml文件中,jar的版本判断的两种途径 1:如果dependenci ...

  4. 034 Maven中的dependencyManagement和dependencies区别

    这个标签使用过,但是具体的描述还是没有说明过.在这里,专门查了一下,写了这篇文章. 1.定义 在Maven中dependencyManagement的作用其实相当于一个对所依赖jar包进行版本管理的管 ...

  5. Maven 梳理 - Maven中的dependencyManagement 意义

    1.在Maven中dependencyManagement的作用其实相当于一个对所依赖jar包进行版本管理的管理器. 2.pom.xml文件中,jar的版本判断的两种途径 1:如果dependenci ...

  6. Maven中<dependencies>节点和<dependencyManagement>节点的区别 转

    以前一直没有在意,今天建立maven工程的时候在<dependencyManagement>节点下加入了junit依赖,结果在dependency Graph中没有发现junit的依赖关系 ...

  7. Maven中<dependencies>节点和<dependencyManagement>节点的区别

    dependencyManagement只是插件管理,并不是真正的插件依赖,所以里面包含的插件在没有子项目使用的时候,并不会真正下载 1 .使用项目继承 利用项目继承可以将结构信息,部署信息,共同的依 ...

  8. Maven 中的dependencies与dependencyManagement的区别

    1.dependencyManagement 在Maven中dependencyManagement的作用其实相当于一个对所依赖jar包进行版本管理的管理器 在pom.xml文件中,jar的版本判断的 ...

  9. Maven中dependencyManagement使用

    在Maven中dependencyManagement的作用其实相当于一个对所依赖jar包进行版本管理的管理器. 在dependencyManagement下申明的dependencies,Maven ...

随机推荐

  1. VMware workstation运维实践系列博客导航

    第一章:VMware workstation虚拟化1.1 VMware workstation计算网络存储介绍1.2 VMware workstation其他功能特性介绍1.3 VMware work ...

  2. TRIO-basic指令--九九乘法表demo

    在路上闲的没事,想到之前自己用别的语言实现乘法口诀表,于是来了兴趣用TRIO-basic试一下,挺简单的一段代码,大家看看就好. ' TRIO-basic '实现乘法口诀表 定义两个整型的局部变量 D ...

  3. SC1243sensor噪点问题调试

    接手一块SC1243sensor的板子调试,仔细核对了原理图和PCB发现,PCB不是很好,电源处理不够好,但是出图了,问题是有噪点,麻点,根据经验要求软件修改了PCLK的极性噪点消失,问题解决. 1: ...

  4. Note: SE Class's Individual Project

    虽然第一个Project还有点小问题需要修改,但是大体已经差不多了,先把blog记在这里,算是开博第一篇吧! 1.项目预计的用时 本来看到这个题的时候想的并不多,但是看了老师的要求才觉得如此麻烦ORZ ...

  5. filter运行出现 <filter object at 0x000001B68F052828> 判断素数

    刚接触filter时  运行总是出现<filter object at 0x000001B68F052828>  得不到想要的数据 后来发现是因为filter的结果是一个数组 需要 lis ...

  6. C 实现选择排序

    一.选择排序的思想 假设有一个7元素的数组 [11, 24, 5, 17, 2, 8, 20],我们通过选择排序来从小到大排序. 思想是进行7次外循环从0-->6,每一次又是一个内循环,从i+1 ...

  7. Linux shell 菜鸟学习笔记....

    20171123 Linux shell 基础学习笔记1. shell 的开始 一般是 #!/bin/bash 通过 #! 来唯一指定使用的shell路径 其他的 # 都表示注释.2. shell 的 ...

  8. Win10 1803 升级之后无法使用 共享目录的解决方法

    1. 自己的虚拟机升级了win10 最新版本 1803 但是发现 使用共享文件夹时报错: 2, 百度发现解决方案还是非常简单的. 需要安装一个 功能 3.方法: 开始 运行 输入 control 打开 ...

  9. [自学]Docker system 命令 查看docker镜像磁盘占用情况 Docker volume 相关

    内容From https://docs.docker.com/engine/reference/commandline/system_df/ docker的image和docker的container ...

  10. [安全]appscan 使用代理抓取其他客户端的请求

    自己安全测试技能很低, 上级给的安全测试的任务给了自动化组的同事来做, 自己之前使用appscan的时候 只知道使用appscan的内置浏览器测试抓取请求 今天与自动化美女同事沟通发现有一个代理的功能 ...