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,则需要显式声明该依赖。

相关推荐
呼啦啦啦啦啦啦啦啦28 分钟前
【Redis】主从模式,哨兵,集群
数据库·redis·缓存
~时泪~42 分钟前
sql主从同步
数据库·sql
予早1 小时前
SQLModel入门
数据库·orm·sqlmodel
ThinkStu1 小时前
2025年时序数据库发展方向和前景分析
数据库·时序数据库
Uncommon.2 小时前
MySQL-索引下推
数据库·mysql
天乐敲代码2 小时前
java-(Oracle)-Oracle,plsqldev,Sql语法,Oracle函数
数据库·oracle
不想起昵称9292 小时前
MySQL
数据库·mysql
tan77º2 小时前
【MySQL】表的操作
开发语言·数据库·c++·mysql
码农幻想梦2 小时前
实验十 Servlet(一)
hive·hadoop·servlet
来恩10033 小时前
C# 字符串与正则表达式介绍
数据库·正则表达式·c#