scope标签控制依赖的可见范围和参与阶段;test仅用于测试编译,不参与主代码编译和运行,不打包;provided用于编译主代码但由外部容器提供,不打包。
区别">
test:只在测试阶段有效
声明为 的依赖,仅在 src/test/java 下的测试代码中可用,编译主代码(src/main/java)和运行时都不可见,也不会打进最终包里。
- 典型例子:JUnit、AssertJ、Mockito
- 如果你在 main 代码里 import junit,Maven 会直接报错——因为编译主代码时它根本不存在
- 打包时完全不包含,避免污染生产环境
provided:编译时需要,运行时由外部提供
表示:这个依赖对编译主代码是必需的,但**运行时由 JDK 或容器(如 Tomcat、Servlet 容器)自带**,所以不会打进最终包里。
- 典型例子:servlet-api、jsp-api、Java EE 相关 API
- 比如你写一个 Web 应用,用到了
HttpServletRequest,编译时必须有 servlet-api.jar;但部署到 Tomcat 时,它自己就提供了,再打进去反而可能冲突 - 注意:Maven 执行
mvn test或mvn compile时,provided 依赖仍参与编译和测试;但mvn package后的 jar/war 里没有它
其他常见 scope 简单对比
顺便提几个常一起出现的 scope,帮你理清边界:
- compile(默认):编译、测试、运行都可用,且会打进包里
- runtime:不需要编译时,但测试和运行时需要(比如 JDBC 驱动)
- system:类似 provided,但需手动指定本地路径(不推荐,破坏可移植性)
基本上就这些。选 test 还是 provided,关键看两点:它是不是只给测试用?还是说“我写代码要它,但上线后别人(JVM/容器)会给我”。搞清这点,配置就不容易出错。










