《Maven官方指南》可选的依赖和依赖排除-Java-优质IT资源分享社区

admin
管理员
管理员
  • UID1
  • 粉丝29
  • 关注4
  • 发帖数581
  • 社区居民
  • 忠实会员
  • 原创写手
阅读:173回复:0

  《Maven官方指南》可选的依赖和依赖排除

楼主#
更多 发布于:2016-05-19 16:22

《Maven官方指南》可选的依赖和依赖排除

原文链接

简介

这节主要讨论了可选的依赖排除功能。这将帮助用户理解它们是什么,怎么使用它们,它们是怎么工作的,和使用它们的最好的方式。同样也解释了为什么排除是在每个依赖的基础上,而不是在POM级别。

可选的依赖

当不可能把一个项目分裂成子模块(不管什么原因)的时候,我们可以使用可选的依赖。它的思想就是:在项目中一些依赖仅仅被某些功能使用,并且如果这个功能不被使用,这个依赖就不需要。理想情况下,根据核心的功能性项目,一个功能被分成子模块…

如果你决定使用子模块的功能,因为你必须需要他们的全部,所以新的子项目仅仅有不可选的依赖。

然而,因为这个项目不可能被分成子模块,所以这些依赖被声明成可选的。如果一个用户想要使用和一个可选的依赖相关的功能,他们将不得不在他们自己的项目中重新声明可选的依赖。用这种方法处理这种情况不是的最好的方式,但是可选的依赖和依赖排除也是一个权宜的解决办法。

为什么使用可选的依赖?

声明可选的依赖,重点不是为了节省空间/内存,因为这些jar最后可能被打进一个WAR、EAR、EJB等,重点是当一个用户为了使用一个项目时来控制实际的依赖列表。包含了一个错误的jar可能会违反一个许可协议,引起环境变量问题等。

怎么使用可选的标签?

在你的依赖声明中,通过简单的设置标签为true,一个依赖就被声明为可选的。一个简单的示例:

...

sample.ProjectA

Project-A

1.0

compile

true

可选的依赖工作原理

Project-A -> Project-B

上面的图意味着项目A依赖于项目B,当A在它的POM文件中把B声明为一个可选的依赖,他们的关系依然没有改变。仅仅就像一次正常的构建,在这次构建中,项目B将会被添加进classpath。

Project-X -> Project-A

但是当一个其他的项目(项目X)在它的POM文件中声明项目A为一个依赖,这个可选的依赖就发挥作用了。你将会注意到项目X的classpath不会包含项目B:为了把B包含进项目X的classpath,你需要在你的POM文件中直接声明。

例子:

有一个名为X2的项目,这个项目和hibernate有一些类似的功能,支持许多数据库驱动/依赖,比如说MySQL,postgre,oracle等。为了构建X2,所有的这些依赖都是必须的,但是对于你的项目来说却不是必须的,所以对于X2把这些依赖声明为可选的是非常实用的,不论什么时候当你在POM文件中把X2声明为一个直接依赖的时候,所有被X2支持的驱动不会自动的被包含进你的项目的classpath,你需要直接声明你将要使用的数据库的依赖/驱动。

依赖排除

因为maven2.X的依赖是传递的,可能会把不想要的依赖包含进你的classpath。比如说

,你所依赖的项目或许没有正确的设置它们的依赖集。为了处理这种特殊的情况,maven2.x包含了依赖排除的概念。排除在你的POM设置了一个特殊的依赖,并目标到一个特殊的groupId和artifactId,当你构建项目的时候,通过声明排除依赖,这个特殊的artifactId不会被添加到你的项目的classpath中。

怎么使用依赖排除:

在pom文件的部分增加标签:

...

sample.ProjectA

Project-A

1.0

compile

sample.ProjectB

Project-B

依赖排除的工作原理和何时使用它(作为最后一招)

Project-A

-> Project-B

-> Project-D

-> Project-E

-> Project-F

-> Project C

上面的图表表示项目A依赖于整个项目B和项目C,项目B依赖于项目D,项目D依赖于项目E和F,默认情况下,项目A的classpath将包含:

B, C, D, E, F

因为我们知道项目D的一些依赖在仓库中丢失了,所以,如果我们不想要把项目D和它的依赖添加到项目A的classpath中会怎样呢?并且你不想要项目B中依赖于项目D的某些功能,在这种情况下,项目B的开发者在项目D的依赖上增加true标签,就像下面这样:

sample.ProjectD

ProjectD

1.0-SNAPSHOT

true

然而,他们并没有这么做。使用最后的手段,你仍然可以把它排除在外,在项目A中,像这样:

4.0.0

sample.ProjectA

Project-A

1.0-SNAPSHOT

jar

...

sample.ProjectB

Project-B

1.0-SNAPSHOT

sample.ProjectD

Project-D

如果我们把项目A部署到仓库,并且项目X声明了一个正常的依赖,依赖于项目A,项目D会被从classpath中排除吗?

Project-X -> Project-A

答案是yes,项目A已经声明了它不需要项目D,所以项目D不会被传递地带到项目A中。

现在,考虑依赖于项目Y的项目X,就像下面表示的一样:

Project-X -> Project-Y

-> Project-B

-> Project-D

...

项目Y同样也有也依赖于项目B,并且它需要一些被项目D支持的特性。因此,不要在这个依赖列表里放置一个对项目D的排除。它或许会供给一个额外的仓库,在这个仓库里,我们可以依赖项目E。在这个例子里,项目D不是被全局排除是非常重要的,因为项目Y有一个合理的依赖。

有另外一种情况,如果我们不想要项目E,而不是项目D,该怎么去排除呢?看看下面的图:

Project-A

-> Project-B

-> Project-D

-> Project-E

-> Project-F

-> Project C

整个依赖的排除工作在我们声明的点下进行。如果你想要排除项目E,你只需要改变排除的点,但是你不能在项目D进行排除,你不能改变项目D的POM文件,如果可以,就会使用可选的依赖而不是排除了,或者简单的把项目D分成子模块,

4.0.0

sample.ProjectA

Project-A

1.0-SNAPSHOT

jar

...

sample.ProjectB

Project-B

1.0-SNAPSHOT

sample.ProjectE

Project-E

为什么排除是在每个依赖的基础上,而不是在POM级别

这用来保证依赖图是可预测的,并从排除一个依赖保持继承效果。如果你采取了最后的手段并放置了一个排除,你应该能绝对的确认哪个依赖被带进了一个不想要的传递依赖。

优质IT资源分享社区为你提供此文。 [font=Tahoma  ]

本站有大量优质Java教程视频,资料等资源,包含java基础教程,高级进阶教程等等,教程视频资源涵盖传智播客,极客学院,达内,北大青鸟,猎豹网校等等IT职业培训机构的培训教学视频,价值巨大。欢迎点击下方链接查看。 [font=Tahoma  ]

java教程视频

优质IT资源分享社区(www.itziyuan.top)
一个免费,自由,开放,共享,平等,互助的优质IT资源分享网站。
专注免费分享各大IT培训机构最新培训教学视频,为你的IT学习助力!

!!!回帖受限制请看点击这里!!!
!!!资源失效请在此版块发帖说明!!!

[PS:按 CTRL+D收藏本站网址~]

——“优质IT资源分享社区”管理员专用签名~

本版相似帖子

游客