Maven optional 关键字透彻图解

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

在 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> 是什么意思呢?spring

optional 关键字的奥秘
老规矩,画个图说明问题:sql

Maven optional 关键字透彻图解

因为 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 依赖,继续看下图:
Maven optional 关键字透彻图解oracle

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

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

实际案例
在 spring-boot-actuator pom.xml 文件中,有超过 20 个依赖是 optional
Maven optional 关键字透彻图解工具

由于 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......

灵魂追问

  • 有不少童鞋项目组用的构建工具时 Gradle,你知道 Gradle 中是怎样表示的吗?
  • 自定义 starter,你知道官方标准 starter 的结构是什么样的吗?
  • 提升效率工具
    Maven optional 关键字透彻图解

推荐阅读

  • Java并发死锁解决思路
  • 锁保护资源,synchronized方法就够了吗
    欢迎持续关注公众号:「日拱一兵」
  • 前沿 Java 技术干货分享
  • 高效工具汇总 | 回复「工具」
  • 面试问题分析与解答
  • 技术资料领取 | 回复「资料」
    以读侦探小说思惟轻松趣味学习 Java 技术栈相关知识,本着将复杂问题简单化,抽象问题具体化和图形化原则逐步分解技术问题,技术持续更新,请持续关注......
    Maven optional 关键字透彻图解

tan日拱一兵转发在看也很赞钟意做者

相关文章
相关标签/搜索