百度360必应搜狗淘宝本站头条
当前位置:网站首页 > 技术文章 > 正文

maven中provided与optional的区别

ccwgpt 2024-12-17 12:58 48 浏览 0 评论

Java 工程中通常使用 maven(当然也有很多人使用 gradle)来管理项目依赖。maven 这样的构建工具极大的提升了工程的构建效率,我们只需要把相关依赖添加至配置文件即可,完全不用关心构建的过程。

在以前的文章中mavendependenciesdependencyManagement的区别介绍过关于dependency 相关的用法,我们知道可以通过 dependency 将依赖添加至 pom.xml 文件中。不过在阅读其他项目的代码,尤其是一些组件端的代码的时候,会发现类似于下面这样的用法:

<dependency>
    <groupId>some.company</groupId>
    <artifactId>project-c</artifactId>
    <optional>true</optional>
</dependency>

<dependency>
    <groupId>some.company</groupId>
    <artifactId>project-d</artifactId>
    <scope>provided</scope>
</dependency>

可能有的人知道 optionalprovided 的作用,他们很快会说出这样是为了简化依赖,避免引入不必要的依赖项。可是二者有什么区别呢?本文就针对这个问题简单的回答下。

optional

关于 optional,最常见的例子就是数据库驱动。例如我们想做一个数据库组件,而且这个数据库组件需要支持多个数据库的话,例如 MySQLPostgreSQLOracle,那么组件端编写的时候将各个数据库的驱动全部引入,像下面这样:

<!-- mysql -->
<dependency>
    <groupId>mysql</groupId>
    <artifactId>mysql-connector-java</artifactId>
</dependency>

<!-- oracle -->
<dependency>
    <groupId>com.oracle</groupId>
    <artifactId>ojdbc14</artifactId>
</dependency>

<!-- PostgreSQL -->
<dependency>
    <groupId>org.postgresql</groupId>
    <artifactId>postgresql</artifactId>
</dependency>

这样数据库组件倒是可以正常开发了,但是这样做的话,构建出的数据库组件,就同时包含了 mysql、oracle、postgresql 三种数据库的驱动包。应用服务引入了我们的数据库组件后,由于依赖传递,就也会同时引入了上面三种数据库驱动包,加大了应用服务打包后的体积,也浪费了资源,甚至可能出现依赖冲突、jar 包冲突的问题。

optional 就是为了解决上述问题。回到上面的场景,分析后发现,实际上的应用服务不太可能同时使用三种不同的数据库,它只需要自己用到的数据库的驱动包就可以了。比如一个使用了 mysql 的服务,是没有必要引入 oracle 的驱动包的。这时候 optional 就派上用处了。optional 表示该依赖是可选的,意味着构建后,标记为 optional 的依赖是不会被一起打入 jar 包的,也不会发生依赖传递。这样不仅我们自己的组件端体积变小了,应用服务也解决了引入过多无用依赖的问题。


<!-- mysql -->
<dependency>
    <groupId>mysql</groupId>
    <artifactId>mysql-connector-java</artifactId>
    <optional>true</optional>
</dependency>

<!-- oracle -->
<dependency>
    <groupId>com.oracle</groupId>
    <artifactId>ojdbc14</artifactId>
    <optional>true</optional>
</dependency>

<!-- PostgreSQL -->
<dependency>
    <groupId>org.postgresql</groupId>
    <artifactId>postgresql</artifactId>
    <optional>true</optional>
</dependency>

按照上面的方式将各个依赖设置为 optional 后,我们打包构建的 jar 将不再包含以上三种数据库的驱动,这样其他应用服务引入了我们的组件后,就不会默认带上上面的数据库驱动包。

可能有同学会疑虑,如果依赖没有带入,那么程序运行期间,会不会发生类找不到的问题?确实是这样的,实际上 optional 表示可选,它将选择权交给了上层应用服务。假如我的服务使用了 mysql,那么我就在服务自己的 pom.xml 中引入 mysql 的驱动包;如果用的是 oracle,同理也是自己引入 oracle 的驱动包,也就是按需使用。如果服务没有引入任何数据库驱动,那么最坏的情况应该是不会使用数据库相关的功能,而不是报错。

其实我理解这里 optional 更是一种规范,规范了以下行为:

  • optional 通常用于组件端应用,即一个 jar 包,而不是一个应用服务;
  • optional 的依赖不会一起被打包,不会经过依赖传递而引入上层应用服务中;
  • optional 的依赖,表示可选,及时没有该依赖,也不影响程序运行,这里需要程序进行一些额外的判断逻辑;
  • optional 的依赖,由上层应用服务来选择是否引入。

举个大白话的例子,去面馆吃面,那么面馆肯定不会把各种调料都放满,而是将选择权交给顾客,顾客按照自己的口味来添加调味料,加不加、加什么,都是顾客自己选。

provided

provided 其实与 optional 非常像,因为从结果来看,二者基本上没有什么区别:标记为 provided 的依赖,和 optional 其实效果是一样的,都不会被直接的打入包中,不会通过依赖传递而传递到上层应用服务的依赖中。那么为什么这里需要把 providedoptional 区分开呢?

这里其实,二者虽然在效果上没有直接的区别,但是二者的使用场景不一样。上面说了 optional 主要用于“可选依赖”的场景,依赖是否引入,都不会影响服务正常运行。而 provided 表示的不是依赖可选,它表示这个依赖是必须的,但是这个依赖通常是已经提供的,应用服务不需要额外引入,通常也不用关心。例如很多人使用 tomcat 作为服务运行容器,tomcat 自己会提供一些必备的依赖项,这些依赖项对于服务正常运行必须的,但是对于应用服务来说,这些依赖项是已经提供好的,不需要自己关心。

所以很多时候,会有人将 optionalprovided 弄混,甚至一起使用,而且通常情况下是没有什么问题的。不过我们还是需要明白二者的区别。虽然二者的行为是一致的,但是对于二者规定的规范确实不同的:

  • optional 表示某个依赖可选,该依赖是否使用都不会影响服务运行。例子:吃面时候,酱油就是可选的,加不加都不会影响面的正常使用。
  • provided 表示某个依赖必须,不过该依赖通常是由系统或者容器提供,不需要自己关系。例子:吃面时候,筷子、碗这样的东西都是必须的,不过这些一般是店家给顾客备好,不需要顾客自带。

相关推荐

css布局方案汇总(28个实例图文并茂)

简介布局在我们前端日常开发来说是非常重要的,一个好的布局能简化代码的同时还能提高网页的性能。常见的布局方法有浮动(float)布局、绝对定位(position)布局、表格布局(table)、弹性(fl...

十款免费的CSS框架加速Web开发

Pure这是Yahoo最新推出的一款CSS框架,它只有HTML和CSS,没有使用任何JavaScript语言。总大小只有4.4kb,但功能却非常丰富,支持响应式样式和各种导航、表格、表单、按钮、网格和...

Tailwind CSS 是不是目前世上最好的CSS框架?

转载说明:原创不易,未经授权,谢绝任何形式的转载今天看了一篇国外大佬对TailwindCSS的看法,在这里分享给大家,看看大家是否赞同,以下是其相关内容的整理,由于翻译水平有限,欢迎大家讨论和指...

下一代 CSS 框架:Mojo CSS,为何如此受欢迎?

TailwindCSS推出即受到广大开发者的欢迎,当前Githubstar数已达77.8k。它是一个功能类优先(utility-first)的CSS框架,它提供了一系列功能类,让开发者...

常见的几种摄影构图方式

摄影构图,是一种在摄影画面中表现结构美、形式美的方式。构图能让摄影主体更加突出,画面更加有序。所以说,构图在摄影中是非常重要的一个环节。无论是前期构图还是后期构图,摄影者都要对构图有一个比较深的了解。...

风光摄影10大构图技巧,会用构图,照片更容易好看

风光摄影10大构图技巧,会用构图,照片更容易好看先解释一下,为什么会使用构图之后,照片更容易好看?因为,构图是根据很多好看的照片,总结出来的技巧,使用这些构图技巧,就相当于站在了巨人的肩膀上,也就是用...

掌握框式构图的摄影技巧,会让摄影爱好者的作品更有魅力!

很多摄影爱好者都知道摄影构图中有个框式构图,但大多数人对框式构图的摄影技巧,却一知半解。所以摄影爱好者们有必要更全面、深入的了解,并掌握框式构图,会对你摄影水平的提高更有帮助。【欢迎点击上方关注:金立...

这个构图很简洁,但为什么不耐看?

摄影爱好者最常犯的错就是过于复杂、主体不明确,但当遇到简单的场景往往又会出现单调、不耐看的状况。为什么会这样?说白了还是观察力不够。下面是本周的摄影入围习作,我们一起来看看这些照片中主体、陪体以及背景...

初学者需要记牢的八种常用构图法

作者:冯海军摄影中,构图很关键,决定照片是否成功,所以在构图上要加以重视和推敲,虽然说构图无定法,但是也有很多的规律可循,以下列举几种常用构图,会对初学者有很大的帮助。多彩刘卫洲摄苏州姑苏俱乐部(...

构图这件事不难!掌握14种构图模式就稳了

如果说视觉元素是视觉信息的载体,那么构图就是视觉元素的载体。没有适当形式的构图对视觉元素有机、有序地承载,平面设计将无法传达预定的设计意图和视觉信息。因此,对于平面设计而言,构图是平面设计不可或缺的重...

框架构图如何使用?

1分钟教你用手机拍大片。今天我们利用框架构图,在不同的运镜方法下拍摄。·首先将手机贴近地面,拍摄人物走过的画面。·然后利用3D效果的背景衬托,将手机贴近地面,以低角度仰拍人物。·最后我们用高清画质来呈...

面构图的5种超实用的构图形式 前景构图,框架构图,填充构图

面构图的5种超实用的构图形式。为什么有的人拍摄的照片好看又舒适?仔细观察会发现他们善用构图。大家好,今天带大家了解摄影中5种超实用的面构图形式。·一、前景构图。前景是构图中的神奇要素,可以提升照片的表...

一看就懂!跟着马格南的大师学构图

马格南图片社是迄今为止全球最重要的摄影图片社,其网站包涵了太多经典的名字和照片。细细品味这些经典图片,能够学到很多有用的构图手法。跟着大师走,总不会错吧?前后景的运用这似乎是非常常见的一种手法,仔细看...

这才是框架构图,有想法!能给你启发么?

框架构图大家并不陌生,但并不是有一个框就行了。框架构图用得不好,就很死板生硬,给人感觉很假。如果你理解透了,拍出的作品不会单调。今天就给大家分享一下框架构图,你看看有哪些妙用?1.广角与长焦的应用长焦...

7B小模型写好学术论文,新框架告别AI引用幻觉

ScholarCopilot团队投稿量子位|公众号QbitAI学术写作通常需要花费大量精力查询文献引用,而以ChatGPT、GPT-4等为代表的通用大语言模型(LLM)虽然能够生成流畅文本,但...

取消回复欢迎 发表评论: