作用
Maven的optional依赖是一种特殊类型的依赖关系,它允许我们将某些依赖项声明为可选。这意味着,只有在项目明确声明需要这个依赖时,它才会被包含在构建中。换句话说,可选依赖不会隐式传递到依赖于当前项目的其他项目中。
以上引用了别人的文章,点击查看原文
例子
spring-boot-autoconfigure项目中很多地方就用到了optional
解释
由于 project C 使用到了两个来自 project A 的类 (OptionalFeatureAClass) 和 project B 的类 (OptionalFeatureBClass). 如果 project C 没有依赖 packageA 和 packageB,那么编译将会失败。
project D 依赖 project C,但是对于 project D 来说,类 (OptionalFeatureAClass) 和类 (OptionalFeatureBClass) 是可选的特性,所以为了让最终的 war/ejb package 不包含不必要的依赖,使用 声明当前依赖是可选的, 默认情况下也不会被其他项目继承(好比 Java 中的 final 类,不能被其他类继承一样)
如果 project D 确实需要用到 project C 中的 OptionalFeatureAClass 怎么办呢?那我们就需要在 project D 的 pom.xml 中显式的添加声明 project A 依赖,继续看下图:
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 驱动吧,所以我们要显式的指定一个,就是这个道理了
以上引用了别人的文章,点击查看原文
示例
我建了三个项目,分别为parent-maven,maven-child,springTest来实践optional的作用。
parent-maven
pom文件
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.example</groupId>
<artifactId>parent-maven</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>parent-maven</name>
<description>parent-maven</description>
<properties>
<java.version>8</java.version>
</properties>
<dependencies>
</dependencies>
</project>
pom文件中什么依赖都没引入,也沒有什么内容。
maven-child
引入了parent-maven依赖,但optional为true,maven-child能引用parent-maven里的类。
pom文件
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.example</groupId>
<artifactId>maven-child</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>maven-child</name>
<description>maven-child</description>
<properties>
<java.version>8</java.version>
<!-- <java.compile>8</java.compile>-->
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot</artifactId>
<version>2.2.0.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-test</artifactId>
<version>2.2.0.RELEASE</version>
</dependency>
<dependency>
<groupId>com.example</groupId>
<artifactId>parent-maven</artifactId>
<version>0.0.1-SNAPSHOT</version>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
<version>2.2.0.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-autoconfigure</artifactId>
<version>2.2.0.RELEASE</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
SpringTest
可以看到我们引入了maven-child,但这个依赖里面却没有parent-maven,这就是optional为true的作用,表示咋们可选择这个依赖。如果你想要parent-maven依赖就得显示的添加该依赖,在spring中@ConditionalOnClass就用到了这种原理。