maven-依赖管理最佳实践

一般一个父pom项目下面常常有好几个子pom项目模块,而且几个子模块依赖的很多jar包,比如groupId/artifactid/version都是相同的,这样有三个弊端:

  1. 造成jar包重复依赖
  2. 造成版本号重复依赖
  3. 升级某个版本号时,要修改好几个子模块

一、在父模块中定义全部dependencies

在父模块中配置dependencies,那样所有子模块都自动继承。

例如在父pom文件中定义好我们需要的全部jar:

<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>

这样子模块只要继承父模块就能直接使用这些jar包,不仅达到了依赖一致的目的,还省掉了大段代码。

然而:这么做是有些不妥的地方,例如某个子模块,比如A不需要父模块log4j的依赖,但也直接继承了,造成了jar包臃肿,多余依赖。

二、在父模块中定义全部dependencyManagement

我们需要一种在父模块中定义好全部的jar包依赖,而子模块需要哪一种指定哪一种,这样既做到了集中式配置,又做到了子模块需要什么配置什么的灵活性。

而dependencyManagement就可以做到。针对这个问题我们可以使用继承机制以及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>

不要的模块,就不需要引入,而dependencyManagement完美的做到了这点。

现在只需要groupId和artifactId,其它元素如version和scope都能通过继承父POM的dependencyManagement得到,如果有依赖配置了exclusions,那节省的代码就更加可观。

但重点不在这,重点在于现在能够保证所有模块使用的JUnit和Log4j依赖配置是一致的。而且子模块仍然可以按需引入依赖, 如果我不配置log4j

dependency,父模块中dependencyManagement下的log4j依赖不会对子模块产生任何影响。

然而,如果在父模块中引入了大量的jar包依赖,这个父模块的dependencyManagement就会包含大量的依赖,如果你想把这些依赖分类以更清晰的管理,那就不可能了。

三、使用import单独出dependencyManagement

此时为了应对父模块中引入了大量的jar包依赖造成父模块臃肿,我们需要一种可以把dependencyManagement放到外面去分开管理,这样很清晰很多,才能更好的管理更多的jar。

而import scope依赖能解决这个问题。

我们可以把dependencyManagement放到单独的专门用来管理依赖的POM中,然后在需要使用依赖的模块中通过import scope依赖,就可以引入dependencyManagement。

1、我们可以写这样一个用于依赖管理的子模块POM:

<project>
  <modelVersion>4.0.0</modelVersion>
  <groupId>wang.conge.demo</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>

2、然后我们的父模块只需要通过非继承的方式来引入这段依赖管理配置:

<dependencyManagement>
    <dependencies>
        <dependency>
          <groupId>wang.conge.demo</groupId>
          <artifactid>sample-dependency-infrastructure</artifactId>
          <version>1.0-SNAPSHOT</version>
          <type>pom</type>
          <scope>import</scope>
        </dependency>
    </dependencies>
  </dependencyManagement>

3、最后我们的子模块需要哪个jar包就引入哪个jar包

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

完美,有没有?

这样,父模块的POM就会非常简洁,由专门的子模块为pom的POM来管理依赖,也契合的面向对象设计中的单一职责原则。

此外,我们还能够创建多个这样的依赖管理POM,以更细化的方式管理依赖。这种做法与面向对象设计中使用组合而非继承也有点相似的味道。

时间: 2024-11-09 14:17:07

maven-依赖管理最佳实践的相关文章

Android 6.0 运行时权限管理最佳实践

Android 6.0 运行时权限管理最佳实践 版权声明:转载必须注明本文转自严振杰的博客: http://blog.yanzhenjie.com 这是一篇迟来的博客,Android M已经发布一年多了(6.0的变化),在Android M中权限系统被重新设计,发生了颠覆性的变化,很多人把握不好这个变化,一是对这个权限策略和套路还没有摸透,二是没有一个很好的实践来支撑,在我的技术开发群里很多人问我关于权限的问题,往往我都没有直接回答,因为这个问题不是一两句说的清楚的,这几点是今天我写这篇博客的原

maven——依赖管理

管理包依赖是 Maven 核心功能之一,下面通过如何引入 jar 包:如何解析 jar 包依赖:包冲突是如何产生:如何解决包冲突:依赖管理解决什么问题:什么是依赖范围:使用包依赖的最佳实践等 6 个问题来介绍. 如何引入 jar 包 在代码开发时,如果需要使用第三方 jar 包提供的类库,那么需要在 pom.xml 加入该 jar 包依赖. 例如:使用 zookeeper client <dependencies> <!-- https://mvnrepository.com/artif

《国际项目集管理最佳实践与实战应用》大型复杂项目与项目群管理工作坊

<国际项目集管理最佳实践与实战应用>大型复杂项目与项目群管理工作坊 Program Management Training 主办单位:共创国际-项目管理者联盟 2015年4月10.11.12日 北京 & 课程前言 项目集(PROGRAM)定义为“经过协调管理以获取单独管理它们时无法取得收益与控制的一组关联的项目和项目集活动.”从组织战略的角度来看,项目集管理主要是指组织为实现其战略目标或为其客户提供整体解决方案而在组织高层针对战略性资源进行跨界整合的管理活动. 在全球经济一体化的背景下

事务管理最佳实践全面解析

事务管理 事务是一个单元的工作,要么全做,要么全不做. 事务管理对于维持数据库系统内部保存的数据逻辑上的一致性.完整性,起着至关重要的作用. 如:一个银行应用软件中,转帐的操作中,需要先在A用户帐户中减去资金,然后再在B用户帐户中增加相应的资金.如果完成A帐户操作后,由于系统故障或者网络故障,没有能够完成接下来的操作,那么A帐户中的资金就白白流失了.显然,客户是无法接受这样的结果的! 如果我们把一个A和B帐户的操作放在一个事务单元中,那么如果遇到上述异常情况,A帐户减少资金的操作会回滚.A帐户的

《项目集管理标准》:全球项目集管理最佳实践

<项目集管理标准>是全球项目集管理最佳实践           <项目集管理标准>(The Standard for Program Management)是由美国项目管理协会推出的一个重要的国家性的,也是事实上的全球性标准.标准详细描述了项目集管理的内容,促进不同项目小组之间进行有效沟通和资源调配.提供了帮助人们理解如何通过提升相互关联的组件的交付能力从而促进组织战略实现的重要且基本的内容.在大多数情况对大部分项目集而言,被认为是清晰.完整的.相关的和公认的在项目集管理中良好实践

密码管理最佳实践

为每个在线网站和服务设置不同的密码,对于保证你使用网络时的安全来说是至关重要的.下面由Personal Technology的专栏作家Geoffrey Fowler,向你展示密码管理程序是如何帮助你记录所有这些登录信息的. 我有超过150个不同的登录项和账户.要记住这么多的密码,我必须成为“雨人”才行.于是我开始搜寻能够储存我所有的密码的最好的服务,最终将名单削减为了四个,它们兼顾了可用性和安全性:1Password.Dachlane.LastPass和PasswordBox. LastPass

Fragment管理最佳实践

现在的app视图中tab+fragment是最常用的一种布局,但是如果使用才是更简洁更有效的呢?下面通过一个demo的分类测试来分析下: add remove replace detach attach hide show这些方法的使用对Fragment生命周期的影响分析: 顺便分析下Fragment所依赖的Activity的生命周期: 测试代码如下: MainActivity的代码如下: package com.testfragmentlifecircle; import android.co

Spring Security 3.2.x与Spring 4.0.x的Maven依赖管理

原文链接: Spring Security with Maven原文日期: 2013年04月24日翻译日期: 2014年06月29日翻译人员: 铁锚 1. 概述 本文通过实例为您介绍怎样使用 Maven 管理 Spring Security 和 Spring 的依赖关系.最新的Spring Security公布版本号能够在 Maven Central仓库 中找到. 译者建议訪问MVNRespotory中org.springframework.security链接.本文是 使用Maven管理Spr

Azure虚拟机管理最佳实践之用户凭据

还记的之前老猫关于通过Powershell远程管理Azure中虚拟机的博文的脚本中,每个虚拟机访问都需要通过get-credential交互方式取得用于访问的用户凭据,但是这这种方式每次都要进行用户交互,如果反复运行的脚本显然不是个好方式,如何加密保留用户的凭据以便反复使用就是个最佳实践的内容.当然现在国际版Azure中提供的自动化服务功能包含的Asset可以安全保留凭据用于自动化脚本调用,由于目前国内的Azure服务还没有这项功能,因此暂时只能按下不表了,当然如果只能这样本文也就结束了,这里介