maven · 2022-10-31 0

maven中optional和scope元素

1.optional 元素

optional 可选值有:true、false

a.传递

optional 是 maven 依赖 jar 时的一个选项,表示该依赖是可选的。默认是 false。

<!-- parent 模块 -->
<modules>
    <module>child1</module>
    <module>child2</module>
</modules>
<!-- child1 模块 -->
<parent>
    <groupId>org.example</groupId>
    <artifactId>parent</artifactId>
    <version>1.0-SNAPSHOT</version>
    <!-- 以当前文件为基准的父工程pom.xml文件的相对路径 -->
    <relativePath>../pom.xml</relativePath>
</parent>

<dependencies>
    <dependency>
        <groupId>commons-lang</groupId>
        <artifactId>commons-lang</artifactId>
        <version>2.6</version>
        <optional>true</optional>
    </dependency>

    <dependency>
        <groupId>org.apache.commons</groupId>
        <artifactId>commons-lang3</artifactId>
        <version>3.12.0</version>
    </dependency>
</dependencies>
<!-- child2 模块 -->
<dependencies>
    <dependency>
        <groupId>org.example</groupId>
        <artifactId>child1</artifactId>
        <version>1.0-SNAPSHOT</version>
    </dependency>
</dependencies>

分析:

zxm@zxm-pc:~/IdeaProjects/parent$ mvn dependency:tree
[INFO] 
[INFO] -------------------------< org.example:parent >-------------------------
[INFO] Building parent 1.0-SNAPSHOT                                       [1/3]
[INFO] --------------------------------[ pom ]---------------------------------
[INFO] 
[INFO] --- maven-dependency-plugin:2.8:tree (default-cli) @ parent ---
[INFO] org.example:parent:pom:1.0-SNAPSHOT
[INFO] 
[INFO] -------------------------< org.example:child1 >-------------------------
[INFO] Building child1 1.0-SNAPSHOT                                       [2/3]
[INFO] --------------------------------[ jar ]---------------------------------
[INFO] 
[INFO] --- maven-dependency-plugin:2.8:tree (default-cli) @ child1 ---
[INFO] org.example:child1:jar:1.0-SNAPSHOT
[INFO] +- commons-lang:commons-lang:jar:2.6:compile
[INFO] \- org.apache.commons:commons-lang3:jar:3.12.0:compile
[INFO] 
[INFO] -------------------------< org.example:child2 >-------------------------
[INFO] Building child2 1.0-SNAPSHOT                                       [3/3]
[INFO] --------------------------------[ jar ]---------------------------------
[INFO] 
[INFO] --- maven-dependency-plugin:2.8:tree (default-cli) @ child2 ---
[INFO] org.example:child2:jar:1.0-SNAPSHOT
[INFO] \- org.example:child1:jar:1.0-SNAPSHOT:compile
[INFO]    \- org.apache.commons:commons-lang3:jar:3.12.0:compile
[INFO] ------------------------------------------------------------------------

child1 向 child2 只传递了 commons-lang3

b.继承

对于继承:
dependencyManagement 设置 optional 无用;
dependencies 设置 optional 值会传递给子模块;

<!-- parent 模块 -->
<modules>
    <module>child1</module>
    <module>child2</module>
</modules>

<dependencyManagement>
    <dependencies>
        <dependency>
            <groupId>commons-lang</groupId>
            <artifactId>commons-lang</artifactId>
            <version>2.6</version>
            <!-- optional 设置无用 -->
            <optional>true</optional>
        </dependency>
    </dependencies>
</dependencyManagement>

<dependencies>
    <dependency>
        <groupId>org.apache.commons</groupId>
        <artifactId>commons-lang3</artifactId>
        <version>3.12.0</version>
        <optional>true</optional>
    </dependency>
</dependencies>
<!-- child1 模块 -->
<parent>
    <groupId>org.example</groupId>
    <artifactId>parent</artifactId>
    <version>1.0-SNAPSHOT</version>
    <!-- 以当前文件为基准的父工程pom.xml文件的相对路径 -->
    <relativePath>../pom.xml</relativePath>
</parent>

<dependencies>
    <dependency>
        <groupId>commons-lang</groupId>
        <artifactId>commons-lang</artifactId>
    </dependency>
</dependencies>
<!-- child2 模块 -->
<dependencies>
    <dependency>
        <groupId>org.example</groupId>
        <artifactId>child1</artifactId>
        <version>1.0-SNAPSHOT</version>
    </dependency>
</dependencies>

分析:

zxm@zxm-pc:~/IdeaProjects/parent$ mvn clean install
zxm@zxm-pc:~/IdeaProjects/parent$ mvn dependency:tree
[INFO] -------------------------< org.example:parent >-------------------------
[INFO] Building parent 1.0-SNAPSHOT                                       [1/3]
[INFO] --------------------------------[ pom ]---------------------------------
[INFO] 
[INFO] --- maven-dependency-plugin:2.8:tree (default-cli) @ parent ---
[INFO] org.example:parent:pom:1.0-SNAPSHOT
[INFO] \- org.apache.commons:commons-lang3:jar:3.12.0:compile
[INFO] 
[INFO] -------------------------< org.example:child1 >-------------------------
[INFO] Building child1 1.0-SNAPSHOT                                       [2/3]
[INFO] --------------------------------[ jar ]---------------------------------
[INFO] 
[INFO] --- maven-dependency-plugin:2.8:tree (default-cli) @ child1 ---
[INFO] org.example:child1:jar:1.0-SNAPSHOT
[INFO] +- commons-lang:commons-lang:jar:2.6:compile
[INFO] \- org.apache.commons:commons-lang3:jar:3.12.0:compile
[INFO] 
[INFO] -------------------------< org.example:child2 >-------------------------
[INFO] Building child2 1.0-SNAPSHOT                                       [3/3]
[INFO] --------------------------------[ jar ]---------------------------------
[INFO] 
[INFO] --- maven-dependency-plugin:2.8:tree (default-cli) @ child2 ---
[INFO] org.example:child2:jar:1.0-SNAPSHOT
[INFO] \- org.example:child1:jar:1.0-SNAPSHOT:compile
[INFO]    \- commons-lang:commons-lang:jar:2.6:compile
[INFO] ------------------------------------------------------------------------

实际生成有效的 child1 pom 为:

<!-- child1-effective-pom.xml -->
<parent>
  <groupId>org.example</groupId>
  <artifactId>parent</artifactId>
  <version>1.0-SNAPSHOT</version>
</parent>

<dependencyManagement>
  <dependencies>
    <dependency>
      <groupId>commons-lang</groupId>
      <artifactId>commons-lang</artifactId>
      <version>2.6</version>
      <optional>true</optional>
    </dependency>
  </dependencies>
</dependencyManagement>

<dependencies>
  <dependency>
    <groupId>commons-lang</groupId>
    <artifactId>commons-lang</artifactId>
    <version>2.6</version>
    <scope>compile</scope>
  </dependency>
  <dependency>
    <groupId>org.apache.commons</groupId>
    <artifactId>commons-lang3</artifactId>
    <version>3.12.0</version>
    <scope>compile</scope>
    <optional>true</optional>
  </dependency>
</dependencies>

child1 继承 parent 有 commons-lang3;child1 向 child2 只传递了 commons-lang。

2.scope 元素

scope 元素主要用来控制依赖的使用范围,指定当前包的依赖范围和依赖的传递性。
常见的可选值有:compile, provided, runtime, test, system、import 等。

  1. compile(编译):compile表示对应依赖会参与当前项目的编译、测试、运行等。打包时通常会包含该依赖,部署时会打包到lib目录下。
  2. test(测试):表示依赖项目仅参与测试环节,在编译、运行、打包时不会使用。
  3. runntime(运行时):runntime仅仅适用于运行和测试环节,在编译环境下不会被使用。比如编译时只需要JDBC API的jar,而只有运行时才需要JDBC驱动实现。
  4. provided(已提供):provided适合在编译和测试的环境,和compile功能相似,但provide仅在编译和测试阶段生效,provide不会被打包,也不具有传递性。
  5. system:system范围依赖与provided类似,不过依赖项不会从maven仓库获取,而需要从本地文件系统提供。使用时,一定要配合systemPath属性。不推荐使用,尽量从Maven库中引用依赖。
  6. import:仅仅在 <dependencyManagement> 内部定义的 pom <dependency> 中支持。

a.compile, provided, runtime, test, system

<!-- parent 模块 -->
<modules>
    <module>child1</module>
    <module>child2</module>
</modules>
<!-- child1 模块 -->
<parent>
    <groupId>org.example</groupId>
    <artifactId>parent</artifactId>
    <version>1.0-SNAPSHOT</version>
    <!-- 以当前文件为基准的父工程pom.xml文件的相对路径 -->
    <relativePath>../pom.xml</relativePath>
</parent>

<dependencies>
    <dependency>
        <groupId>commons-lang</groupId>
        <artifactId>commons-lang</artifactId>
        <version>2.6</version>
    </dependency>

    <dependency>
        <groupId>junit</groupId>
        <artifactId>junit</artifactId>
        <version>4.12</version>
        <scope>test</scope>
    </dependency>

    <dependency>
        <groupId>mysql</groupId>
        <artifactId>mysql-connector-java</artifactId>
        <version>8.0.20</version>
        <scope>runtime</scope>
    </dependency>

    <dependency>
        <groupId>javax.servlet</groupId>
        <artifactId>javax.servlet-api</artifactId>
        <version>3.1.0</version>
        <scope>provided</scope>
    </dependency>

    <dependency>
        <groupId>sun.jdk</groupId>
        <artifactId>tools</artifactId>
        <version>1.5.0</version>
        <scope>system</scope>
        <systemPath>${java.home}/../lib/tools.jar</systemPath>
    </dependency>
</dependencies>
<!-- child2 模块 -->
<dependencies>
    <dependency>
        <groupId>org.example</groupId>
        <artifactId>child1</artifactId>
        <version>1.0-SNAPSHOT</version>
    </dependency>
</dependencies>

分析:

zxm@zxm-pc:~/IdeaProjects/parent$ mvn clean install
zxm@zxm-pc:~/IdeaProjects/parent$ mvn dependency:tree
[INFO] -------------------------< org.example:parent >-------------------------
[INFO] Building parent 1.0-SNAPSHOT                                       [1/3]
[INFO] --------------------------------[ pom ]---------------------------------
[INFO] 
[INFO] --- maven-dependency-plugin:2.8:tree (default-cli) @ parent ---
[INFO] org.example:parent:pom:1.0-SNAPSHOT
[INFO] 
[INFO] -------------------------< org.example:child1 >-------------------------
[INFO] Building child1 1.0-SNAPSHOT                                       [2/3]
[INFO] --------------------------------[ jar ]---------------------------------
[INFO] 
[INFO] --- maven-dependency-plugin:2.8:tree (default-cli) @ child1 ---
[INFO] org.example:child1:jar:1.0-SNAPSHOT
[INFO] +- commons-lang:commons-lang:jar:2.6:compile
[INFO] +- junit:junit:jar:4.12:test
[INFO] |  \- org.hamcrest:hamcrest-core:jar:1.3:test
[INFO] +- mysql:mysql-connector-java:jar:8.0.20:runtime
[INFO] |  \- com.google.protobuf:protobuf-java:jar:3.6.1:runtime
[INFO] +- javax.servlet:javax.servlet-api:jar:3.1.0:provided
[INFO] \- sun.jdk:tools:jar:1.5.0:system
[INFO] 
[INFO] -------------------------< org.example:child2 >-------------------------
[INFO] Building child2 1.0-SNAPSHOT                                       [3/3]
[INFO] --------------------------------[ jar ]---------------------------------
[INFO] 
[INFO] --- maven-dependency-plugin:2.8:tree (default-cli) @ child2 ---
[INFO] org.example:child2:jar:1.0-SNAPSHOT
[INFO] \- org.example:child1:jar:1.0-SNAPSHOT:compile
[INFO]    +- commons-lang:commons-lang:jar:2.6:compile
[INFO]    +- mysql:mysql-connector-java:jar:8.0.20:runtime
[INFO]    |  \- com.google.protobuf:protobuf-java:jar:3.6.1:runtime
[INFO]    \- sun.jdk:tools:jar:1.5.0:system
[INFO] ------------------------------------------------------------------------

child1 向 child2 传递 compile,runtime,system,不传递 test,provided

b.import

import 使用,表示这些 dependencyManagement 的 dependency可以等价于直接在当前pom文件中定义的,而不是从父项目继承来的。

<!-- parent 模块 -->
<modules>
    <module>child1</module>
    <module>child2</module>
</modules>
<!-- child1 模块 -->
<groupId>org.example</groupId>
<artifactId>child1</artifactId>
<version>1.0-SNAPSHOT</version>
<packaging>pom</packaging>

<dependencyManagement>
    <dependencies>
        <dependency>
            <groupId>commons-lang</groupId>
            <artifactId>commons-lang</artifactId>
            <version>2.6</version>
        </dependency>
    </dependencies>
</dependencyManagement>

<dependencies>
    <dependency>
        <groupId>org.apache.commons</groupId>
        <artifactId>commons-lang3</artifactId>
        <version>3.12.0</version>
    </dependency>
</dependencies>
<!-- child2 模块 -->
<dependencyManagement>
    <dependencies>
        <dependency>
            <groupId>org.example</groupId>
            <artifactId>child1</artifactId>
            <version>1.0-SNAPSHOT</version>
            <type>pom</type>
            <scope>import</scope>
        </dependency>
    </dependencies>
</dependencyManagement>

实际生成有效的 child2 pom 为:

<!-- child2-effective-pom.xml -->
<dependencyManagement>
  <dependencies>
    <dependency>
      <groupId>commons-lang</groupId>
      <artifactId>commons-lang</artifactId>
      <version>2.6</version>
    </dependency>
  </dependencies>
</dependencyManagement>