大型项目的依赖包管理
Java的世界里,几乎所有项目的包管理都是使用了Maven,或者在其之上演进的组件。大型项目比如有成百上千个工程,依赖的包比较多,如果没有统一的版本管理,很容易就失控了。
依赖包版本冲突
项目中pom.xml来管理依赖包,会遵循一个最短路径依赖。先看一个Case
<dependencies>
<dependency>
<groupId>com.dangdang</groupId>
<artifactId>elastic-job-lite-spring</artifactId>
<version>2.1.5</version>
</dependency>
<dependency>
<groupId>com.lihongkun.labs</groupId>
<artifactId>jmh</artifactId>
<version>1.0-SNAPSHOT</version>
</dependency>
</dependencies>
如上代码,项目中依赖了两个jar包,他们各自的依赖如下图
可以看到这两个包的依赖树如图,其中的gson包版本是不一致的。按照最短路径原则的化2.2.2版本的包它的路径是比较短的。所以选择了2.2.2版本。我们可以使用 mvn dependency:tree命令来看最后选择的依赖。
这种情况下,会导致应用无法启动。因为elasticjob的使用强依赖于2.6.1,而其中使用的功能在2.2.2不存在。解决这种版本冲突比较简单,直接使用更短的路径依赖去覆盖,即在本项目中显式指定依赖和版本。但是当项目比较多的时候,坏处就显而易见了。
依赖包版本管理
BOM(Bill of Materials)是由Maven提供的功能,它通过定义一整套相互兼容的jar包版本集合,使用时只需要依赖该BOM文件,即可放心的使用需要的依赖jar包,且无需再指定版本号。BOM的维护方负责版本升级,并保证BOM中定义的jar包版本之间的兼容性。
如何使用
典型的应用如 使用Spring框架时,直接引入其bom进行包依赖管理。在使用具体的包时则不需要再进行包版本的声明。
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-framework-bom</artifactId>
<version>4.3.1.RELEASE</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-web</artifactId>
</dependency>
<dependencies>
如何自定义
既然有这样好处,那么我们在平时项目的管理中如何编写BOM。建议是整个部门或者大的项目由一个统一的BOM进行管理。
<groupId>com.lihongkun.labs</groupId>
<artifactId>bom</artifactId>
<version>1.0</version>
<packaging>pom</packaging>
<dependencyManagement>
<!--声明依赖和版本-->
<dependencies>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid</artifactId>
<version>1.1.12</version>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
<version>1.2.29</version>
</dependency>
<dependencies>
</dependencyManagement>
编写方式同平时进行包依赖引入的时候没什么差别。只是所有的依赖都是使用dependencyManagement这个标签包含起来。
<!--引入bom进行依赖管理-->
<dependencyManagement>
<dependencies>
<dependency>
<groupId>com.lihongkun.labs</groupId>
<artifactId>bom</artifactId>
<version>1.0</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
<!--声明本项目所需要的依赖-->
<dependencies>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid</artifactId>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
<!--指定版本号进行覆盖-->
<version>1.2.66</version>
</dependency>
<dependencies>
使用了上述方式即可直接对其中声明的包进行统一的版本管理。如上述代码,fastjson在本项目中需要进行一个单独升级,那么可以直接指定版本号进行覆盖。框架虽然留下了这种灵活性,但是实际使用中最好是进行统一管理。
如果团队中经常出现包管理的问题,不妨使用以下BOM,会有意想不到的效果。
- Python通过抓包和使用cookie爬取微博完全讲解
- (50) 剖析EnumMap / 计算机程序的思维逻辑
- 认识九大经典sql模式
- 构建一个pip安装的车辆路径显示的Python包
- 如何编写复杂sql
- Python机器学习工具:Scikit-Learn介绍与实践
- (51) 剖析EnumSet / 计算机程序的思维逻辑
- mysql性能优化的几条重要建议
- Python爬虫抓取知乎所有用户信息
- Eclipse远程调试出现“JDWP Transport dt_socket failed to initialize”的解决方案
- Django 博客教程:前言和环境安装(连载一)
- (52) 抽象容器类 / 计算机程序的思维逻辑
- mysql的查询、子查询及连接查询
- 简陋的分布式爬虫(附项目代码地址)
- JavaScript 教程
- JavaScript 编辑工具
- JavaScript 与HTML
- JavaScript 与Java
- JavaScript 数据结构
- JavaScript 基本数据类型
- JavaScript 特殊数据类型
- JavaScript 运算符
- JavaScript typeof 运算符
- JavaScript 表达式
- JavaScript 类型转换
- JavaScript 基本语法
- JavaScript 注释
- Javascript 基本处理流程
- Javascript 选择结构
- Javascript if 语句
- Javascript if 语句的嵌套
- Javascript switch 语句
- Javascript 循环结构
- Javascript 循环结构实例
- Javascript 跳转语句
- Javascript 控制语句总结
- Javascript 函数介绍
- Javascript 函数的定义
- Javascript 函数调用
- Javascript 几种特殊的函数
- JavaScript 内置函数简介
- Javascript eval() 函数
- Javascript isFinite() 函数
- Javascript isNaN() 函数
- parseInt() 与 parseFloat()
- escape() 与 unescape()
- Javascript 字符串介绍
- Javascript length属性
- javascript 字符串函数
- Javascript 日期对象简介
- Javascript 日期对象用途
- Date 对象属性和方法
- Javascript 数组是什么
- Javascript 创建数组
- Javascript 数组赋值与取值
- Javascript 数组属性和方法
- codeforce893C (并查集)
- codeforces 544C(完全背包求方案数)
- SCU2511(单调栈)
- B. Ternary String(贪心)
- codeforces 940B(贪心)
- codeforces 429A(dfs)
- codeforces 1182B (DFS)
- codeforces 509B(构造,思维)
- codeforces 1257C(map)
- codeforces 977D(DFS)
- codeforces 580C(dfs)
- codeforces 1155B(博弈)
- XXXXX codeforces1364A(数学)
- JAVA入门学习十一
- codeforces 1282B(dp)