可选依赖与依赖管理
optional 标记可选依赖,阻断依赖传递,减少不必要的依赖引入。
optional 概念
定义
可选依赖不会被传递给依赖该项目的外部项目。
对比
| 特性 | 普通依赖 | 可选依赖 |
|---|---|---|
| 当前项目可用 | ✓ | ✓ |
| 传递给外部 | ✓ | ✗ |
配置可选依赖
基本语法
XML
<dependency>
<groupId>com.example</groupId>
<artifactId>optional-lib</artifactId>
<version>1.0.0</version>
<optional>true</optional>
</dependency>
常见可选依赖
XML
<!-- 日志实现可选 -->
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-simple</artifactId>
<version>1.7.36</version>
<optional>true</optional>
</dependency>
<!-- 数据库驱动可选 -->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>8.0.28</version>
<optional>true</optional>
</dependency>
可选依赖场景
场景1:多实现可选
XML
<!-- 提供多种数据库驱动可选 -->
<dependencies>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>8.0.28</version>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.postgresql</groupId>
<artifactId>postgresql</artifactId>
<version>42.3.0</version>
<optional>true</optional>
</dependency>
</dependencies>
使用者选择需要的驱动。
场景2:工具库可选依赖
XML
<!-- 工具库可选依赖序列化库 -->
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.13.0</version>
<optional>true</optional>
</dependency>
使用者根据需要引入序列化库。
场景3:编译时依赖
XML
<!-- 仅编译时需要 -->
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.18.24</version>
<optional>true</optional>
</dependency>
optional vs exclusions
区别
| 方式 | 说明 |
|---|---|
| optional | 提供方声明不传递 |
| exclusions | 使用方排除传递依赖 |
提供方控制
XML
<!-- 提供方 -->
<dependency>
<groupId>com.example</groupId>
<artifactId>feature-lib</artifactId>
<optional>true</optional> <!-- 不传递 -->
</dependency>
使用方控制
XML
<!-- 使用方 -->
<dependency>
<groupId>com.example</groupId>
<artifactId>some-lib</artifactId>
<exclusions>
<exclusion>
<groupId>com.example</groupId>
<artifactId>feature-lib</artifactId>
</exclusion>
</exclusions>
</dependency>
可选依赖使用
使用方手动引入
XML
<!-- 依赖包含可选依赖的库 -->
<dependency>
<groupId>com.example</groupId>
<artifactId>core-lib</artifactId>
<version>1.0.0</version>
</dependency>
<!-- 手动引入可选依赖 -->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>8.0.28</version>
</dependency>
依赖图示例
使用 optional
Bash
core-lib
├── common(传递)
└── mysql-driver(optional,不传递)
使用 core-lib:
├── common(自动获得)
└── mysql-driver(需手动引入)
不使用 optional
text
core-lib
├── common(传递)
└── mysql-driver(传递)
使用 core-lib:
├── common(自动获得)
└── mysql-driver(自动获得)
查看可选依赖
text
mvn dependency:tree
可选依赖显示 (optional):
text
[INFO] +- com.example:core-lib:jar:1.0.0:compile
[INFO] | +- com.example:common:jar:1.0.0:compile
[INFO] | +- mysql:mysql-connector-java:jar:8.0.28:compile (optional)
最佳实践
适用场景
| 场景 | 使用 optional |
|---|---|
| 多实现可选 | ✓ |
| 编译时依赖 | ✓ |
| 条件依赖 | ✓ |
| 核心依赖 | ✗ |
不适用场景
- 核心运行时依赖不应可选
- API 依赖不应可选
- 被大多数使用者需要的依赖
要点总结
- optional=true 标记可选依赖
- 可选依赖不传递给外部项目
- 使用者需手动引入可选依赖
- 适用于多实现可选、编译时依赖
- 核心依赖不应标记可选
- dependency:tree 显示
(optional)标记
📝 发现内容有误?点击此处直接编辑