Maven(Ⅱ):依赖范围,依赖传递,依赖阻断,可选依赖

1. Maven 依赖范围

概念

依赖范围(Dependency Scope)用于控制依赖在不同构建阶段的可见性和可用性。Maven 定义了几种不同的依赖范围,每种范围都有其特定的使用场景。

常见依赖范围及用途
  • compile:默认的依赖范围,在所有的 classpath 中都可用,并且会传递到依赖的项目中。适用于项目的核心业务代码依赖。
  • provided:该依赖在编译和测试阶段可用,但在运行时由 JDK 或容器提供。例如 Servlet API,在 Tomcat 等容器中已经包含,不需要打包到项目中。
  • runtime:该依赖在运行和测试阶段需要,但在编译阶段不需要。例如 JDBC 驱动,编译时只需要 JDBC 接口,运行时才需要具体的驱动实现。
  • test:该依赖仅在测试编译和运行阶段可用,不会影响项目的正常运行。例如 JUnit 测试框架。
  • system :类似于 provided,但需要显式指定依赖的本地路径。这种方式不推荐使用,因为它破坏了 Maven 的依赖管理机制。
  • import :只能在 <dependencyManagement> 中使用,用于导入其他 pom.xml<dependencyManagement> 部分。
代码示例
xml 复制代码
<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 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>com.example</groupId>
    <artifactId>dependency-demo</artifactId>
    <version>1.0-SNAPSHOT</version>

    <dependencies>
        <!-- compile 范围 -->
        <dependency>
            <groupId>commons-lang</groupId>
            <artifactId>commons-lang</artifactId>
            <version>2.6</version>
        </dependency>
        <!-- provided 范围 -->
        <dependency>
            <groupId>javax.servlet</groupId>
            <artifactId>javax.servlet-api</artifactId>
            <version>4.0.1</version>
            <scope>provided</scope>
        </dependency>
        <!-- runtime 范围 -->
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <version>8.0.26</version>
            <scope>runtime</scope>
        </dependency>
        <!-- test 范围 -->
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>4.13.2</version>
            <scope>test</scope>
        </dependency>
    </dependencies>
</project>

2. Maven 依赖传递

概念

依赖传递是指当一个项目依赖另一个项目时,被依赖项目的依赖也会自动传递到当前项目中。这可以减少项目 pom.xml 中依赖声明的数量,但也可能导致依赖冲突。

代码示例

假设我们有三个项目:project-aproject-bproject-c

project-bpom.xml
xml 复制代码
<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 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>com.example</groupId>
    <artifactId>project-b</artifactId>
    <version>1.0-SNAPSHOT</version>

    <dependencies>
        <dependency>
            <groupId>commons-lang</groupId>
            <artifactId>commons-lang</artifactId>
            <version>2.6</version>
        </dependency>
    </dependencies>
</project>
project-apom.xml
xml 复制代码
<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 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>com.example</groupId>
    <artifactId>project-a</artifactId>
    <version>1.0-SNAPSHOT</version>

    <dependencies>
        <dependency>
            <groupId>com.example</groupId>
            <artifactId>project-b</artifactId>
            <version>1.0-SNAPSHOT</version>
        </dependency>
    </dependencies>
</project>

由于 project-a 依赖 project-b,而 project-b 依赖 commons-lang,所以 commons-lang 会通过依赖传递自动成为 project-a 的依赖。

3. Maven 依赖阻断

概念

依赖阻断是指在依赖传递过程中,通过某种方式阻止某些依赖传递到当前项目中。通常是因为这些依赖会导致冲突或不必要的开销。

代码示例

假设 project-c 依赖 project-b,但不希望 project-bcommons-lang 依赖传递过来。

project-cpom.xml
xml 复制代码
<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 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>com.example</groupId>
    <artifactId>project-c</artifactId>
    <version>1.0-SNAPSHOT</version>

    <dependencies>
        <dependency>
            <groupId>com.example</groupId>
            <artifactId>project-b</artifactId>
            <version>1.0-SNAPSHOT</version>
            <!-- 排除 commons-lang 依赖 -->
            <exclusions>
                <exclusion>
                    <groupId>commons-lang</groupId>
                    <artifactId>commons-lang</artifactId>
                </exclusion>
            </exclusions>
        </dependency>
    </dependencies>
</project>

通过 <exclusions> 标签可以排除传递过来的依赖。

4. Maven 可选依赖

概念

可选依赖(Optional Dependencies)是指在声明依赖时,将其标记为可选。这样,当其他项目依赖当前项目时,这些可选依赖不会自动传递。

代码示例

假设 project-d 依赖 commons-lang,并且将其标记为可选。

project-dpom.xml
xml 复制代码
<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 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>com.example</groupId>
    <artifactId>project-d</artifactId>
    <version>1.0-SNAPSHOT</version>

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

当其他项目依赖 project-d 时,commons-lang 不会作为传递依赖被引入。如果其他项目需要 commons-lang,则需要显式声明该依赖。

相关推荐
ClouGence7 小时前
Oracle CDC 架构优化:从主库直连到 DataGuard 备库同步
数据库·后端·oracle
无响应de神9 小时前
三、用户与权限管理
数据库·mysql
小宇宙Zz1 天前
Maven依赖冲突
java·服务器·maven
麦聪聊数据1 天前
数据服务化时代:企业数据能力输出的核心路径
数据库
王小王-1231 天前
基于 Hive 的网易云音乐数据分析及可视化系统
hive·hadoop·数据分析·音乐数据分析·网易云音乐分析·hive音乐分析·hadoop网易云
shushangyun_1 天前
2026年快消品B2B系统推荐:支持终端门店订货、促销政策自动化的工具?
java·运维·网络·数据库·人工智能·spring·自动化
DARLING Zero two♡1 天前
【MySQL数据库】数据类型与表约束
数据库·mysql
曹牧1 天前
Oracle EXPLAIN PLAN
数据库·oracle
BD_Marathon1 天前
SQL学习指南——视图
数据库·sql
活宝小娜1 天前
mysql详细安装教程
数据库·mysql·adb