maven dependency中scope=compile 和 provided区别

问题再现:
上次这边朋友问我一个问题,就是他们在pom.xml中的dependency中,看到有一些是<scope>provided</scope>的情况,比如如下:

<dependency> 
<groupId>com.liferay.portal</groupId>
<artifactId>portal-impl</artifactId>
<version>6.1.0</version>
<scope>provided</scope>
</dependency>


他们问我scope在何种情况下要设置为provided,以及和scope设置为compile的区别。

[color=blue][b]解释:[/b][/color]
其实这个问题很简单。
对于scope=compile的情况(默认scope),也就是说这个项目在编译,测试,运行阶段都需要这个artifact对应的jar包在classpath中。
而对于scope=provided的情况,则可以认为这个provided是目标容器已经provide这个artifact。换句话说,它只影响到编译,测试阶段。在编译测试阶段,我们需要这个artifact对应的jar包在classpath中,而在运行阶段,假定目标的容器(比如我们这里的liferay容器)已经提供了这个jar包,所以无需我们这个artifact对应的jar包了。

听起来很玄乎,对吧,其实一点也不难理解。举个scope=provided的例子。
比如说,假定我们自己的项目ProjectABC 中有一个类叫C1,而这个C1中会import这个portal-impl的artifact中的类B1,那么在编译阶段,我们肯定需要这个B1,否则C1通不过编译,因为我们的scope设置为provided了,所以编译阶段起作用,所以C1正确的通过了编译。测试阶段类似,故忽略。
那么最后我们要吧ProjectABC部署到Liferay服务器上了,这时候,我们到$liferay-tomcat-home\webapps\ROOT\WEB-INF\lib下发现,里面已经有了一个portal-impl.jar了,换句话说,容器已经提供了这个artifact对应的jar,所以,我们在运行阶段,这个C1类直接可以用容器提供的portal-impl.jar中的B1类,而不会出任何问题。

[color=darkblue][b]实际插件的行为:[/b][/color]
刚才我们讲述的是理论部分,现在我们看下,实际插件在运行时候,是如何来区别对待scope=compile和scope=provided的情况的。

做一个实验就可以很容易发现,[color=red][size=medium][b]当我们用maven install生成最终的构件包ProjectABC.war后,在其下的WEB-INF/lib中,会包含我们被标注为scope=compile的构件的jar包,而不会包含我们被标注为scope=provided的构件的jar包。这也避免了此类构件当部署到目标容器后产生包依赖冲突。[/b][/size][/color]

参考:http://supercharles888.blog.51cto.com/609344/981316/
### Maven 中 `<scope>provided</scope>` 的作用含义 #### 1. 定义与作用 在 Maven 中,`<scope>provided</scope>` 指定了依赖项的作用范围。这种作用范围表示该依赖项在编译测试阶段是可用的,但在运行时由容器或 JDK 提供,因此不需要将其打包到最终的应用程序中[^1]。例如,当开发一个 Web 应用程序时,Servlet API 是必需的用于编译代码,但运行时 Servlet 容器(如 Tomcat)已经提供了这些类,因此无需将 Servlet API 打包到应用程序中。 #### 2. 使用场景 `<scope>provided</scope>` 的典型使用场景包括以下几种情况: - 当开发 Java EE 应用程序时,某些依赖项(如 JSP、Servlet、JNDI 等)由应用服务器提供,因此这些依赖项不需要包含在最终的 WAR 或 EAR 文件中[^2]。 - 在使用某些框架时(如 Log4j),如果框架已经由运行环境提供,则可以将这些依赖项标记为 `provided`。 以下是一个示例,展示如何在 `pom.xml` 中配置 `provided` 范围的依赖项: ```xml <dependency> <groupId>javax.servlet</groupId> <artifactId>javax.servlet-api</artifactId> <version>4.0.1</version> <scope>provided</scope> </dependency> ``` 在此示例中,`javax.servlet-api` 被标记为 `provided`,这意味着它将在编译测试阶段可用,但在运行时由 Servlet 容器提供[^3]。 #### 3. 与其他 Scope区别 为了更好地理解 `provided` 的含义,以下是它与其他常见 Scope 的对比: - **compile**:默认 Scope,适用于所有阶段(编译、测试、运行),并且会被打包到最终产物中。 - **test**:仅在测试阶段可用,不会被打包到最终产物中。 - **runtime**:在运行时需要但在编译时不需要的依赖项,例如 JDBC 驱动程序。 - **provided**:在编译测试阶段可用,但在运行时由容器或 JDK 提供,因此不会被打包到最终产物中[^1]。 #### 4. 注意事项 - 如果错误地将应该标记为 `provided` 的依赖项设置为 `compile`,可能会导致重复加载问题或版本冲突。 - 确保运行环境中确实提供了所需的依赖项,否则应用程序可能无法正常运行。 ```python # 示例 Python 代码块(非相关,仅为演示格式) def example_function(): print("This is an example function") ```
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值