maven中的scope理解,你学会了吗?

背景

新来同事搭建了一个springBoot项目,启动失败,如下提示Web application could not be started as there was no org.springframework.boot.web.servlet.server.ServletWebServerFactory bean defined in the context.

我比较纳闷,按说spring-boot-starter-web模块自带tomcat web容器啊,于是我就去看maven:

xml 复制代码
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-web</artifactId>
    <exclusions>
        <exclusion>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-tomcat</artifactId>
        </exclusion>
    </exclusions>
</dependency>
    <!-- undertow-->
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-undertow</artifactId>
    <scope>provided</scope>
</dependency>

果不其然,同事在web模块排除了tomcat依赖,同时添加了undertow,但是scope指定的是provided级别,我记得provided在编译、测试时有效,但是在运行时无效,所以果断修改为compile,项目能够成功启动。

总结原因,还是对maven的scope知识点没有掌握牢固,今天我们简单总结一下。

scope取值与解释

Maven中使用 scope 来指定当前包的依赖范围和依赖的传递性。常见的可选值有:compile, provided, runtime, test, system 等。scope 主要是用在 pom.xml 文件中的依赖定义部分。

1. compile (默认)

描述 :compile 是 Maven 中的默认作用域,不指定 scope 的依赖会自动使用 compile 作用域。 使用阶段 :编译、测试、运行、打包。 特点 :在项目的所有阶段都可用。通常用于项目在运行时和编译时都需要的依赖。 典型场景 :项目的核心依赖,比如 Spring Framework、Hibernate 等通常会设为 compile。 示例

xml 复制代码
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter</artifactId>
    <version>${spring-boot.version}</version>
    <!-- scope 默认为 compile -->
</dependency>

2. provided

描述 :provided 表示依赖在编译和测试阶段可用,但在运行时不会打包进最终的构件(如 JAR 或 WAR)。 使用阶段 :编译、测试。 特点 :运行时需要在外部提供这些依赖,比如应用服务器或运行环境会提供它们。 典型场景 :Servlet API、JSP API 等应用服务器或容器内置的库。 示例

xml 复制代码
<dependency>
    <groupId>javax.servlet</groupId>
    <artifactId>javax.servlet-api</artifactId>
    <version>4.0.1</version>
    <scope>provided</scope>
</dependency>

3. runtime

描述 :runtime 作用域的依赖仅在运行和测试阶段可用,编译时不可用。 使用阶段 :运行、测试。 特点 :通常用于运行时才需要的库,编译时不需要。 典型场景 :数据库驱动。应用在编译时不需要数据库驱动,但运行时需要。 示例

xml 复制代码
<dependency>
    <groupId>mysql</groupId>
    <artifactId>mysql-connector-java</artifactId>
    <version>8.0.26</version>
    <scope>runtime</scope>
</dependency>

4. test

描述 :test 作用域的依赖仅在测试阶段可用,编译、运行时不可用。 使用阶段 :测试。 特点 :用于编写和运行测试时需要的库。 典型场景 :JUnit、spring-boot-starter-test。 示例

xml 复制代码
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-test</artifactId>
    <version>${spring-boot.version}</version>
    <scope>test</scope>
</dependency>

5. system

描述 :system 作用域的依赖明确指定依赖文件的路径。它不会从 Maven 仓库中下载,而是直接使用本地系统的文件。作用域功能上类似于provided。 使用阶段 :编译、测试。 特点 :对文件路径有硬编码,无法与其他机器共享路径信息,不推荐使用。 典型场景 :通常不建议使用,可能用于一些本地库或特殊环境下的文件。 示例

xml 复制代码
<dependency>
    <groupId>com.xiaoyu</groupId>
    <artifactId>freedom</artifactId>
    <version>1.0.0</version>
    <scope>system</scope>
    <systemPath>${project.basedir}/libs/freedom.jar</systemPath>
</dependency>

6. import(仅适用于 )

描述 :import 作用域主要用于导入依赖的 BOM(Bill of Materials)文件,它通常在 中使用,用于控制和管理子项目的版本一致性。 使用阶段 :不直接用于编译或运行,而是用来将依赖版本管理导入到主项目。 典型场景 :用于多模块项目或需要版本统一的第三方依赖管理,如 Spring Boot 的 BOM。 示例

xml 复制代码
<dependencyManagement>
    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-dependencies</artifactId>
            <version>${spring-boot.version}</version>
            <type>pom</type>
            <scope>import</scope>
        </dependency>
    </dependencies>
</dependencyManagement>

依赖传递

当项目 A 依赖项目 B,而项目 B 又依赖项目 C 时,Maven 会自动将项目 C 也作为项目 A 的依赖引入。这种自动处理依赖关系的特性称为传递性依赖。

传递规则取决于 Scope:

当前依赖Scope \ 传递依赖Scope compile provided runtime test
compile compile - runtime -
provided provided provided provided -
runtime runtime - runtime -
test - - - - weix
相关推荐
一碗谦谦粉1 分钟前
Maven 依赖调解的两大原则
java·maven
苦学编程的谢9 小时前
Maven
java·maven·intellij-idea
考虑考虑9 小时前
Maven 依赖范围(Scope)
java·后端·maven
程序员张319 小时前
Maven编译和打包插件
java·spring boot·maven
代码的余温1 天前
5种高效解决Maven依赖冲突的方法
java·maven
paishishaba1 天前
Maven
java·maven
代码的余温2 天前
Maven引入第三方JAR包实战指南
java·maven·jar
Wyc724092 天前
Maven
java·数据库·maven
逆风局?2 天前
Maven高级——分模块设计与开发
java·maven