Maven optional关键字透彻图解

简介: Maven optional关键字透彻图解

写在前面


本来想写一篇「如何自定义Spring Boot Starter」,但是为了更好理解 Starter 的一些设计理念和其中的关键点,所以提前将一些细节内容单独提取出来讲解说明


在 Maven pom.xml 中,你经常会看到依赖项中有类似下面的代码:


<dependency>
  <groupId>sample.ProjectA</groupId>
  <artifactId>Project-A</artifactId>
  <version>1.0</version>
  <scope>compile</scope>
  <optional>true</optional> 
</dependency>


这里的 <optional>true</optional> 是什么意思呢?


optional 关键字的奥秘


老规矩,画个图说明问题:


微信图片_20220510104934.png


由于 project C 使用到了两个来自 project A 的类 (OptionalFeatureAClass) 和 project B 的类 (OptionalFeatureBClass). 如果 project C 没有依赖 packageA 和 packageB,那么编译将会失败。


project D 依赖 project C,但是对于 project D 来说,类 (OptionalFeatureAClass) 和类 (OptionalFeatureBClass) 是可选的特性,所以为了让最终的 war/ejb package 不包含不必要的依赖,使用<optional> 声明当前依赖是可选的, 默认情况下也不会被其他项目继承(好比 Java 中的 final 类,不能被其他类继承一样)


如果 project D 确实需要用到 project C 中的 OptionalFeatureAClass 怎么办呢?那我们就需要在 project D 的 pom.xml 中显式的添加声明 project A 依赖,继续看下图:


微信图片_20220510104959.png


Project D 需要用到 Project A 的 OptionalFeatureAClass,那么需要在 Project D 的 pom.xml 文件中显式的添加对 Project A 的依赖


到这也就很好理解为什么 Maven 为什么要设计 optional 关键字了,假设一个关于数据库持久化的项目(Project C), 为了适配更多类型的数据库持久化设计,比如 Mysql 持久化设计(Project A) 和 Oracle 持久化设计(Project B),当我们的项目(Project D) 要用的 Project C 的持久化设计,不可能既引入 mysql 驱动又引入 oracle 驱动吧,所以我们要显式的指定一个,就是这个道理了


实际案例


spring-boot-actuator pom.xml 文件中,有超过 20 个依赖是 optional


image.jpeg


因为 Spring Boot 不可能将没必要的依赖也打包到你最终的 jar package 中,所以用到 spring boot actuator 的项目最终生成的 jar package 中不会包含这 20 多个依赖 jar,如果你要用到哪一个,显式的加入到你的项目就好了


在接下来的文章,自定义 Spring Boot Starter 也是这个策略,因为 starter 是包含特定功能为其他项目服务用的,类似本文的 Project C 的角色了,到这里你理解 optional 的奥秘了吗?


反向应用


如果 Project C 引入的依赖没有加 <optional>true</optional>,Project D 又需要依赖 Project C,但只用到 Project A 的类怎么办呢?Maven 也是有解决办法的,使用 exclusion 关键字,不多说,上一段代码就懂了:


<dependencies>
    <dependency>
      <groupId>top.dayarch.demo</groupId>
      <artifactId>Project-C</artifactId>
      <exclusions>
        <exclusion>
          <groupId>top.dayarch.demo</groupId>
          <artifactId>Project-B</artifactId>
        </exclusion>
      </exclusions> 
    </dependency>
</dependencies>


总结


到这里,在你今后设计功能性依赖时,你应该明白怎样设计依赖关系了, 我这里推荐使用 optional 的形式,简单来说,你设计的依赖什么菜都有,想吃什么菜自己 "抱蔡明" 就好,接下来我们就模拟官方标准创建自定义的 starter......  访问恢复正常,欢迎交流


灵魂追问


  1. 有很多童鞋项目组用的构建工具时 Gradle,你知道 Gradle 中是怎样表示的吗?


  1. 自定义 starter,你知道官方标准 starter 的结构是什么样的吗?


相关文章
|
7月前
|
Java API Maven
maven中scope和optional区别
maven中scope和optional区别
100 1
|
Java Maven
Maven Optional & Exclusions使用区别
Optional和Exclusions都是用来排除jar包依赖使用的,两者在使用上却是相反。 Optional定义后,该依赖只能在本项目中传递,不会传递到引用该项目的父项目中,父项目需要主动引用该依赖才行。 Exclusions则是主动排除子项目传递过来的依赖。
313 0
|
关系型数据库 Java Maven
maven可选依赖(Optional Dependencies)和依赖排除(Dependency Exclusions)
我们知道,maven的依赖关系是有传递性的。如:A-->B,B-->C。但有时候,项目A可能不是必需依赖C,因此需要在项目A中排除对A的依赖。在maven的依赖管理中,有两种方式可以对依赖关系进行,分别是可选依赖(Optional Dependencies)以及依赖排除(Dependency Exclusions)。
1855 0
|
Java Maven
Maven - pom.xml 文件中 dependency 中 optional 属性
Maven - pom.xml 文件中 dependency 中 optional 属性
464 0
|
Java 测试技术 数据库连接
Maven中optional和scope元素的使用,你弄明白了?
Maven中optional和scope元素的使用,你弄明白了?
730 0
Maven中optional和scope元素的使用,你弄明白了?
|
人工智能 Java 大数据
Maven Optional & Exclusions使用区别
Optional和Exclusions都是用来排除jar包依赖使用的,两者在使用上却是相反。 Optional定义后,该依赖只能在本项目中传递,不会传递到引用该项目的父项目中,父项目需要主动引用该依赖才行。
1309 0
|
14天前
|
XML Java 测试技术
从零开始学 Maven:简化 Java 项目的构建与管理
Maven 是一个由 Apache 软件基金会开发的项目管理和构建自动化工具。它主要用在 Java 项目中,但也可以用于其他类型的项目。
30 1
从零开始学 Maven:简化 Java 项目的构建与管理
|
29天前
|
Java Maven
maven项目的pom.xml文件常用标签使用介绍
第四届人文,智慧教育与服务管理国际学术会议(HWESM 2025) 2025 4th International Conference on Humanities, Wisdom Education and Service Management
87 8
|
26天前
|
Java 应用服务中间件 Maven
Maven的三种项目打包方式——pom,jar,war的区别
Maven 提供了多种打包方式,分别适用于不同类型的项目。pom 用于父项目或聚合项目,便于项目的结构和依赖管理;jar 用于Java类库或可执行的Java应用程序;war 则专用于Java Web应用程序的部署。理解这些打包方式的用途和特点,可以帮助开发者更好地配置和管理Maven项目,确保构建和部署过程的顺利进行。无论是单模块项目还是多模块项目,选择合适的打包方式对于项目的成功至关重要。
66 3