必须使用provided范围:当依赖仅需参与编译和测试、但须排除在最终打包产物外(如tomcat已提供的servlet-api),否则会因重复类引发classcastexception或noclassdeffounderror。
☞☞☞AI 智能聊天, 问答助手, AI 智能搜索, 多模态理解力帮你轻松跨越从0到1的创作门槛☜☜☜

在 Maven 项目中,当你需要让某个依赖只参与编译和测试、但明确排除在最终打包产物之外时,就必须区分 compile 和 provided 范围——比如你正在开发一个部署到 Tomcat 的 Web 应用,而 servlet-api.jar 已由 Tomcat 自带,若错误地用 compile 引入,会导致 WAR 包里出现重复的 javax.servlet.* 类,引发 ClassCastException 或 NoClassDefFoundError。
compile 是默认范围,全生命周期可用
直接在 pom.xml 的 <dependency></dependency> 中不写 <scope></scope> 标签,或显式写成 <scope>compile</scope>,该依赖就会被纳入编译、测试、运行三阶段,并被打包进最终产物(如 JAR/WAR)。
它还会传递给下游依赖该项目的其他模块——也就是说,如果 A 项目 compile 引入了 B,C 项目依赖 A,那么 C 的 classpath 里也会自动带上 B。
这一步操作起来很简单,直接把 dependency 块粘贴进去就行,无需额外配置。
provided 只参与编译和测试,打包时被剔除
当你确认目标运行环境(如 JDK、Tomcat、Jetty、云平台)已自带某依赖时,才应使用 <scope>provided</scope>。
方法一:手动修改 pom.xml
在 dependency 块内添加 <scope>provided</scope>,例如:<dependency><br> <groupid>javax.servlet</groupid><br> <artifactid>javax.servlet-api</artifactid><br> <version>4.0.1</version><br> <scope>provided</scope><br></dependency>
方法二:IDE 快捷插入(以 IntelliJ IDEA 为例)
① 在 Project Structure → Modules → Dependencies 中选中对应依赖 → 点击右侧 Scope 下拉框 → 选择 【Provided】;
② 点击 OK 后,IDE 会自动在 pom.xml 中补上 <scope>provided</scope>;
③ 【必须执行 mvn clean compile 验证】——否则 IDE 缓存可能仍保留旧 classpath,导致编译通过但运行时报错。
注意:provided 依赖不会出现在最终构建产物的 WEB-INF/lib/(WAR)或 lib/(JAR)目录下,也不会传递给其他项目。
关键区别验证方式
第一步:执行 mvn clean package 构建项目;
第二步:解压生成的 WAR/JAR 文件;
第三步:检查 WEB-INF/lib/ 或根目录 lib/ 中是否存在该依赖的 JAR;
→ 若存在,说明用了 compile(或未设 scope);
→ 若不存在,且编译、测试均通过,则说明 provided 生效。
这一步不能跳过——很多开发者误以为只要写了 provided 就万事大吉,结果发现运行时报 ClassNotFoundException,其实是容器环境没提供对应版本,或本地测试时忘了启动容器。











