Java Maven依赖管理最佳工程实践

本文介绍了Java Maven项目中进行依赖管理的一些最佳实践,包括在properties中声明版本、注意依赖声明顺序、使用BOM文件、确定依赖作用范围,以及正确处理日志依赖,旨在解决依赖冲突、版本不一致等问题,提高项目维护效率。
摘要由CSDN通过智能技术生成

一般的Java工程项目都使用了Meven进行依赖管理(另外一些会使用Gradle进行管理,例如Android项目等,这里不再阐述了)。Meven在引入依赖是很方便的,只要有(groupId, artifactId, version)三元组,就可以引入一个依赖。但是,实际使用中有时会碰到一些棘手的问题,可能会踩坑很久。比如:

  • 依赖冲突问题,经典的log4j日志组件依赖冲突,网上有大量遇到这种问题的文章。
  • 版本不对齐问题,例如使用Spring框架时需要引用spring-core,spring-context等子模块包,如果这些依赖的版本不一致,例如一个版本是3.1.2,另一个版本是4.1.3,就可能发生兼容问题。
  • 多模块依赖管理问题,项目需要划分为多个子模块,同时希望这些子模块能够使用一样版本的依赖,如果在每个模块里每次都声明版本,则在后续的维护可能会出现疏漏。
  • 依赖不规范问题,项目需要发布为Jar包提供给其他服务作为接口包或sdk接口使用,却因为引入了Spring-boot包,导致引入了这个包的服务因为本来并不是使用Spring-Boot框架的服务,启动出现失败,但这个接口或sdk又需要对Spring-Boot服务做一些支持逻辑而需要引用Spring-Boot包。

这里主要说一些在依赖管理上的一些最佳实践,帮助从工程上能够尽量减少这些问题的发生。

1. 在properties中声明一组相同版本的依赖

对一些一组相同版本的依赖,可以通过properties标签里声明一个环境变量,然后使用这个变量通配符声明版本,这个变量通配符就会映射为在properties定义的值。如下面配置所示。

<properties>
    <spring.version>5.2.3.RELEASE</spring.version>
</properties>

<dependencies>
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-core</artifactId>
        <version>${spring.version}</version>
    </dependency>
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-context</artifactId>
        <version>${spring.version}</version>
    </dependency>
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-expression</artifactId>
        <version>${spring.version}</version>
    </dependency>
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-web</artifactId>
        <version>${spring.version}</version>
    </dependency>
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-webmvc</artifactId>
        <version>${spring.version}</version>
    </dependency>
</dependencies>

例如在使用Spring框架时通常需要引入一系列的包,这些包需要保证版本一致,通过定义变量spring.version,如同编程语言里变量一样,后面声明时直接引用变量名,就可以保证所使用的版本就是变量的值5.2.3.RELEASE

而且在后续如果要升级Spring版本,只要修改spring.version就可以了,不用再往下一个个翻着找Spring的依赖然后修改,(有时候pom文件会很长),减少升级成本。

一种规范化的做法是,所有的依赖的版本都声明在properties里,按xxx.version来定义,这个根据个人实际的喜好来,建议一些对项目比较重要的依赖将版本,以及一组相同依赖的版本声明到properties标签里。

2. 注意依赖声明的顺序

依赖是有优先级判断原则的,如果有多个依赖间接使用了同一个依赖,那么会使用引用路径最短的版本,如果最短路径的依赖有多个,那就找最先声明的版本。

例如项目P依此引用A, B, C包,然后各个包的依赖依此是 A->D->E(1.0), B->E(1.0), C->E(2.0), 那实际引用的E的版本是1.0

有时候这种依赖判断原则会出现一些问题,例如,如果C是项目P的子模块,在C里已经声明了依赖E的版本是2.0, 而B只是一个第三方工具依赖,它间接依赖了旧的版本1.0, 在上面的声明顺序就会导致项目P引用了老的版本1.0,从而可能到服务跑起来时才发现E的版本不对的问题,严重时会导致线上事故。

所以,依赖声明的顺序还是很重要的,下面给一个比较推荐的依赖声明顺序。

  • 最先声明本模块依赖项目的其他项目子模块,例如exapmle-dao, example-service , example-api 三个子模块,那不管三七二十一example-service里先声明引用exapmle-dao
  • 其次声明通用基础组件的依赖,比如spring、jackson (fastjson经常爆漏洞,不推荐再使用了)、log4j等。
  • 其次声明公司基础框架依赖,例如RPC框架、Redis客户端等
  • 其次声明本模块特定使用的依赖,保证这些特定的依赖不会覆盖上面的依赖。
  • 最后声明中需要使用的测试依赖,例如junit、assert4j等

3. 使用bom统一管理基础依赖的版本1

除了像spring那样需要引用一致的版本之外,有时候一些不同依赖之间是也是有一定的版本要求的,这个经常发生在需要使用大量公司提供的基础组件依赖的场景里,这些基础组件相互之间存在引用,如果有其中的版本不对有可能会出现奇奇怪怪的问题。这时候可以使用bom将版本统一起来。

BOM 是Bill Of Materials的缩写,就是说在这个bom里把一系列组件的依赖的版本都声明好了,同时人工去保证这些版本之间不会出现严重的冲突或兼容性问题,确定好没有问题之后发布该bom文件,后续项目需要引用这些组件时,

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值