建设商务网站作用,做个外贸网站多少费用,前端h5是什么意思,建网站和开发app哪个难依赖关系管理是Maven的核心功能。管理单个项目的依赖关系很容易。管理由数百个模块组成的多模块项目和应用程序的依赖关系是可能的。Maven在定义、创建和维护具有良好定义的类路径和库版本的可复制构建方面有很大帮助。
一、传递依赖
Maven通过自动包含可传递的依赖关系…依赖关系管理是Maven的核心功能。管理单个项目的依赖关系很容易。管理由数百个模块组成的多模块项目和应用程序的依赖关系是可能的。Maven在定义、创建和维护具有良好定义的类路径和库版本的可复制构建方面有很大帮助。
一、传递依赖
Maven通过自动包含可传递的依赖关系避免了发现和指定您自己的依赖关系所需的库的需要。 通过从指定的远程存储库中读取依赖项的项目文件可以实现此功能。通常这些项目的所有依赖项都会在项目中使用项目从其父项或依赖项继承的任何依赖项也是如此依此类推。 可以从中收集依赖关系的级别数量没有限制。只有当发现循环依赖关系时才会出现问题。 有了可传递的依赖关系包含库的图可以很快变大。因此还有一些附加功能限制了所包含的依赖项
依赖项中介 - 这决定了在遇到多个版本作为依赖项时将选择哪个版本的项目。Maven选择了“最接近的定义”。也就是说它使用依赖项树中与项目最近的依赖项的版本。您始终可以通过在项目的 POM 中显式声明版本来保证版本。请注意如果两个依赖项版本在依赖项树中的深度相同则第一个声明优先。 “最接近的定义”意味着使用的版本将是依赖项树中与您的项目最接近的版本。考虑以下依赖树 A├── B│ └── C│ └── D 2.0└── E└── D 1.0 在文本中A、B和C的依赖项定义为A-B-C-D2.0和A-E-D1.0然后在构建A时将使用D1.0因为从A到D通过E的路径更短。您可以在a中显式地向D2.0添加依赖项以强制使用D2.0如下所示 A├── B│ └── C│ └── D 2.0├── E│ └── D 1.0│└── D 2.0
依赖项管理-这允许项目作者在传递依赖项或未指定版本的依赖项中遇到工件时直接指定要使用的工件版本。在上一节的例子中一个依赖项被直接添加到a中尽管a没有直接使用它。相反a可以将D作为依赖项包含在其dependencyManagement部分中并直接控制在何时或是否引用它时使用D的哪个版本。依赖关系范围-这允许您只包括适用于构建的当前阶段的依赖关系。下面将对此进行更详细的描述。排除的依赖项-如果项目X依赖于项目Y而项目Y依赖于项目Z则项目X的所有者可以使用“排除”元素将项目Z明确排除为依赖项。可选依赖项-如果项目Y依赖于项目Z则项目Y的所有者可以使用“可选”元素将项目Z标记为可选依赖项。当项目X依赖于项目Y时X将仅依赖于Y而不依赖于Y的可选依赖项Z。然后项目X的所有者可以根据自己的选择显式添加对Z的依赖项。将可选依赖项视为“默认排除”可能会有所帮助)
尽管可传递依赖项可以隐式地包括所需的依赖项但显式指定源代码直接使用的依赖项是一种很好的做法。这种最佳实践证明了它的价值尤其是当项目的依赖关系改变了它们的依赖关系时。 例如假设您的项目A指定了对另一个项目B的依赖项而项目B指定了对项目C的依赖项。如果您直接在项目C中使用组件而您没有在项目A中指定项目C则当项目B突然更新/删除其对项目C的依赖时可能会导致生成失败。 直接指定依赖项的另一个原因是它为您的项目提供了更好的文档只需读取项目中的POM文件或者执行mvn-dependency:tree就可以了解更多信息。 Maven还提供了dependency:analyze插件分析依赖关系的目标这有助于使这种最佳实践更容易实现。
二、依赖范围
依赖关系范围用于限制依赖关系的传递性并确定依赖关系何时包含在类路径中。 共有6个作用域
compile 这是默认范围如果未指定则使用。编译依赖项在项目的所有类路径中都可用。此外这些依赖项将传播到依赖项目。
provided 这很像编译但表示您希望JDK或容器在运行时提供依赖关系。例如当为Java Enterprise Edition构建web应用程序时您需要将对Servlet API和相关Java EE API的依赖设置为所提供的范围因为web容器提供了这些类。具有此作用域的依赖项被添加到用于编译和测试的类路径中但不添加到运行时类路径中。它不可传递。
runtime 此范围表示编译不需要依赖项而是执行依赖项。Maven在运行时和测试类路径中包含一个具有此作用域的依赖项但不包括编译类路径。
test
此范围表示应用程序的正常使用不需要依赖项仅适用于测试编译和执行阶段。此范围不可传递。通常这个范围用于JUnit和Mockito等测试库。它也用于非测试库如Apache Commons IO如果这些库用于单元测试src/test/java但不用于模型代码src/main/java。
system 这个作用域与提供的作用域类似只是您必须提供显式包含它的JAR。工件总是可用的并且不会在存储库中查找。
import 只有dependencyManagement部分中pom类型的依赖项才支持此作用域。它指示依赖项将被指定POM的dependencyManagement部分中的有效依赖项列表所取代。由于它们被替换具有导入范围的依赖项实际上并没有参与限制依赖项的传递性。
每个作用域导入除外都以不同的方式影响可传递的依赖项如下表所示。如果将依赖项设置为左列中的作用域则该依赖项与顶行中作用域的可传递依赖项将导致主项目中的依赖项与交叉点处列出的作用域。如果没有列出作用域则表示省略了依赖项。 compile provided runtime test compile compile(*) - runtime - provided provided - provided - runtime runtime - runtime - test test - test -
*注意这应该是运行时范围因此必须显式列出所有编译依赖项。但是如果您所依赖的库从另一个库扩展了一个类则两者在编译时都必须可用。由于这个原因编译时依赖关系仍然是编译范围即使它们是可传递的。
三、依赖关系管理
依赖关系管理部分是一种用于集中依赖关系信息的机制。当您有一组从公共父级继承的项目时可以将有关依赖项的所有信息放在公共 POM 中并对子 POM 中的项目进行更简单的引用。通过一些例子可以最好地说明这种机制。给定扩展同一父级的这两个 POM
项目A
project...dependenciesdependencygroupIdgroup-a/groupIdartifactIdartifact-a/artifactIdversion1.0/versionexclusionsexclusiongroupIdgroup-c/groupIdartifactIdexcluded-artifact/artifactId/exclusion/exclusions/dependencydependencygroupIdgroup-a/groupIdartifactIdartifact-b/artifactIdversion1.0/versiontypebar/typescoperuntime/scope/dependency/dependencies
/project
项目B
project...dependenciesdependencygroupIdgroup-c/groupIdartifactIdartifact-b/artifactIdversion1.0/versiontypewar/typescoperuntime/scope/dependencydependencygroupIdgroup-a/groupIdartifactIdartifact-b/artifactIdversion1.0/versiontypebar/typescoperuntime/scope/dependency/dependencies
/project
这两个示例 POM 共享一个共同的依赖项并且每个都有一个非平凡的依赖项。此信息可以像这样放入父 POM 中 project...dependencyManagementdependenciesdependencygroupIdgroup-a/groupIdartifactIdartifact-a/artifactIdversion1.0/versionexclusionsexclusiongroupIdgroup-c/groupIdartifactIdexcluded-artifact/artifactId/exclusion/exclusions/dependencydependencygroupIdgroup-c/groupIdartifactIdartifact-b/artifactIdversion1.0/versiontypewar/typescoperuntime/scope/dependencydependencygroupIdgroup-a/groupIdartifactIdartifact-b/artifactIdversion1.0/versiontypebar/typescoperuntime/scope/dependency/dependencies/dependencyManagement
/project
然后两个子 POM 变得更加简单
project...dependenciesdependencygroupIdgroup-a/groupIdartifactIdartifact-a/artifactId/dependencydependencygroupIdgroup-a/groupIdartifactIdartifact-b/artifactId!-- This is not a jar dependency, so we must specify type. --typebar/type/dependency/dependencies
/project
project...dependenciesdependencygroupIdgroup-c/groupIdartifactIdartifact-b/artifactId!-- This is not a jar dependency, so we must specify type. --typewar/type/dependencydependencygroupIdgroup-a/groupIdartifactIdartifact-b/artifactId!-- This is not a jar dependency, so we must specify type. --typebar/type/dependency/dependencies
/project 注意在其中两个依赖引用中我们必须指定type/元素。这是因为用于将依赖引用与dependencyManagement节匹配的最小信息集实际上是{groupIdartifactIdtypeclassifier}。在许多情况下这些依赖关系将引用没有分类器的jar工件。这允许我们将标识集简写为{groupIdartifactId}因为类型字段的默认值是jar而默认分类器是null。 依赖关系管理部分的第二个也是非常重要的用途是控制可传递依赖关系中使用的工件的版本。以这些项目为例
项目A
projectmodelVersion4.0.0/modelVersiongroupIdmaven/groupIdartifactIdA/artifactIdpackagingpom/packagingnameA/nameversion1.0/versiondependencyManagementdependenciesdependencygroupIdtest/groupIdartifactIda/artifactIdversion1.2/version/dependencydependencygroupIdtest/groupIdartifactIdb/artifactIdversion1.0/versionscopecompile/scope/dependencydependencygroupIdtest/groupIdartifactIdc/artifactIdversion1.0/versionscopecompile/scope/dependencydependencygroupIdtest/groupIdartifactIdd/artifactIdversion1.2/version/dependency/dependencies/dependencyManagement
/project
项目B
projectparentartifactIdA/artifactIdgroupIdmaven/groupIdversion1.0/version/parentmodelVersion4.0.0/modelVersiongroupIdmaven/groupIdartifactIdB/artifactIdpackagingpom/packagingnameB/nameversion1.0/versiondependencyManagementdependenciesdependencygroupIdtest/groupIdartifactIdd/artifactIdversion1.0/version/dependency/dependencies/dependencyManagementdependenciesdependencygroupIdtest/groupIdartifactIda/artifactIdversion1.0/versionscoperuntime/scope/dependencydependencygroupIdtest/groupIdartifactIdc/artifactIdscoperuntime/scope/dependency/dependencies
/project 当maven在项目B上运行时无论POM中指定的版本是什么都将使用工件a、B、c和d的1.0版本。
a和c都被声明为项目的依赖项因此由于依赖项中介使用1.0版本。两者都有运行时作用域因为它是直接指定的。b是在b的父级依赖关系管理部分中定义的由于对于可传递依赖关系依赖关系管理优先于依赖关系中介因此如果在a或c的POM中引用它将选择1.0版本。b也将具有编译范围。最后由于d是在B的依赖关系管理部分中指定的如果d是a或c的依赖关系或传递依赖关系则将选择1.0版本这也是因为依赖关系管理优先于依赖关系中介也因为当前POM的声明优先于其父声明。
有关依赖项管理标记的引用信息可从项目描述符引用中获得。
四、正在导入依赖项
上一节中的示例描述了如何通过继承指定托管依赖项。然而在较大的项目中这可能是不可能实现的因为一个项目只能从单亲继承。为了适应这种情况项目可以从其他项目导入托管依赖项。这是通过将POM工件声明为范围为“import”的依赖项来实现的。
Project B:
projectmodelVersion4.0.0/modelVersiongroupIdmaven/groupIdartifactIdB/artifactIdpackagingpom/packagingnameB/nameversion1.0/versiondependencyManagementdependenciesdependencygroupIdmaven/groupIdartifactIdA/artifactIdversion1.0/versiontypepom/typescopeimport/scope/dependencydependencygroupIdtest/groupIdartifactIdd/artifactIdversion1.0/version/dependency/dependencies/dependencyManagementdependenciesdependencygroupIdtest/groupIdartifactIda/artifactIdversion1.0/versionscoperuntime/scope/dependencydependencygroupIdtest/groupIdartifactIdc/artifactIdscoperuntime/scope/dependency/dependencies
/project
假设A是前面例子中定义的POM那么最终结果将是相同的。A的所有托管依赖项都将被合并到B中除了d因为它是在这个POM中定义的。
Project X:
projectmodelVersion4.0.0/modelVersiongroupIdmaven/groupIdartifactIdX/artifactIdpackagingpom/packagingnameX/nameversion1.0/versiondependencyManagementdependenciesdependencygroupIdtest/groupIdartifactIda/artifactIdversion1.1/version/dependencydependencygroupIdtest/groupIdartifactIdb/artifactIdversion1.0/versionscopecompile/scope/dependency/dependencies/dependencyManagement
/project
Project Y:
projectmodelVersion4.0.0/modelVersiongroupIdmaven/groupIdartifactIdY/artifactIdpackagingpom/packagingnameY/nameversion1.0/versiondependencyManagementdependenciesdependencygroupIdtest/groupIdartifactIda/artifactIdversion1.2/version/dependencydependencygroupIdtest/groupIdartifactIdc/artifactIdversion1.0/versionscopecompile/scope/dependency/dependencies/dependencyManagement
/project
Project Z:
projectmodelVersion4.0.0/modelVersiongroupIdmaven/groupIdartifactIdZ/artifactIdpackagingpom/packagingnameZ/nameversion1.0/versiondependencyManagementdependenciesdependencygroupIdmaven/groupIdartifactIdX/artifactIdversion1.0/versiontypepom/typescopeimport/scope/dependencydependencygroupIdmaven/groupIdartifactIdY/artifactIdversion1.0/versiontypepom/typescopeimport/scope/dependency/dependencies/dependencyManagement
/project
在上面的示例中Z从X和Y导入托管依赖项。然而X和Y都包含依赖项a。这里将使用a的1.1版本因为X是首先声明的而a不是在Z的dependencyManagement中声明的。 这个过程是递归的。例如如果X导入另一个POM Q那么当Z被处理时它将简单地显示出Q的所有托管依赖项都是在X中定义的。
五、BOM表POM
当用于定义通常是多项目构建的一部分的相关工件的“库”时导入最有效。一个项目使用这些库中的一个或多个工件是相当常见的。然而有时很难使用工件来保持项目中的版本与库中分发的版本同步。下面的模式说明了如何创建“BOM表”BOM以供其他项目使用。 项目的根是BOM POM。它定义了将在库中创建的所有工件的版本。其他希望使用库的项目应该将此POM导入其POM的dependencyManagement部分。
project xmlnshttp://maven.apache.org/POM/4.0.0 xmlns:xsihttp://www.w3.org/2001/XMLSchema-instancexsi:schemaLocationhttp://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsdmodelVersion4.0.0/modelVersiongroupIdcom.test/groupIdartifactIdbom/artifactIdversion1.0.0/versionpackagingpom/packagingpropertiesproject1Version1.0.0/project1Versionproject2Version1.0.0/project2Version/propertiesdependencyManagementdependenciesdependencygroupIdcom.test/groupIdartifactIdproject1/artifactIdversion${project1Version}/version/dependencydependencygroupIdcom.test/groupIdartifactIdproject2/artifactIdversion${project2Version}/version/dependency/dependencies/dependencyManagementmodulesmoduleparent/module/modules
/project
父子项目将BOM POM作为其父项目。这是一个正常的多项目pom。
project xmlnshttp://maven.apache.org/POM/4.0.0 xmlns:xsihttp://www.w3.org/2001/XMLSchema-instancexsi:schemaLocationhttp://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsdmodelVersion4.0.0/modelVersionparentgroupIdcom.test/groupIdversion1.0.0/versionartifactIdbom/artifactId/parentgroupIdcom.test/groupIdartifactIdparent/artifactIdversion1.0.0/versionpackagingpom/packagingdependencyManagementdependenciesdependencygroupIdlog4j/groupIdartifactIdlog4j/artifactIdversion1.2.12/version/dependencydependencygroupIdcommons-logging/groupIdartifactIdcommons-logging/artifactIdversion1.1.1/version/dependency/dependencies/dependencyManagementmodulesmoduleproject1/modulemoduleproject2/module/modules
/project 接下来是实际的项目POM
project xmlnshttp://maven.apache.org/POM/4.0.0 xmlns:xsihttp://www.w3.org/2001/XMLSchema-instancexsi:schemaLocationhttp://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsdmodelVersion4.0.0/modelVersionparentgroupIdcom.test/groupIdversion1.0.0/versionartifactIdparent/artifactId/parentgroupIdcom.test/groupIdartifactIdproject1/artifactIdversion${project1Version}/versionpackagingjar/packagingdependenciesdependencygroupIdlog4j/groupIdartifactIdlog4j/artifactId/dependency/dependencies
/projectproject xmlnshttp://maven.apache.org/POM/4.0.0 xmlns:xsihttp://www.w3.org/2001/XMLSchema-instancexsi:schemaLocationhttp://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsdmodelVersion4.0.0/modelVersionparentgroupIdcom.test/groupIdversion1.0.0/versionartifactIdparent/artifactId/parentgroupIdcom.test/groupIdartifactIdproject2/artifactIdversion${project2Version}/versionpackagingjar/packagingdependenciesdependencygroupIdcommons-logging/groupIdartifactIdcommons-logging/artifactId/dependency/dependencies
/project
下面的项目显示了现在如何在另一个项目中使用库而不必指定依赖项目的版本
project xmlnshttp://maven.apache.org/POM/4.0.0 xmlns:xsihttp://www.w3.org/2001/XMLSchema-instancexsi:schemaLocationhttp://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsdmodelVersion4.0.0/modelVersiongroupIdcom.test/groupIdartifactIduse/artifactIdversion1.0.0/versionpackagingjar/packagingdependencyManagementdependenciesdependencygroupIdcom.test/groupIdartifactIdbom/artifactIdversion1.0.0/versiontypepom/typescopeimport/scope/dependency/dependencies/dependencyManagementdependenciesdependencygroupIdcom.test/groupIdartifactIdproject1/artifactId/dependencydependencygroupIdcom.test/groupIdartifactIdproject2/artifactId/dependency/dependencies
/project 最后在创建导入依赖项的项目时请注意以下事项
请勿尝试导入在当前POM的子模块中定义的POM。尝试这样做将导致构建失败因为它将无法定位POM。切勿将导入POM的POM声明为目标POM的父级或祖级等。无法解析循环将引发异常。当引用其POM具有可传递依赖性的工件时项目需要将这些工件的版本指定为托管依赖性。不这样做会导致生成失败因为工件可能没有指定版本。在任何情况下这都应该被视为最佳实践因为它防止工件的版本从一个构建更改到下一个构建。
从Maven4.0开始引入了一种新的特定BOM打包。它允许定义一个BOM表该BOM表在利用较新的4.1.0模型的项目中不用作父级同时仍然提供与Maven 3.X客户端和项目的完全兼容性。在安装/部署时利用Maven 4的构建/消费者POM功能将此BOM打包转换为更常见的POM打包。因此这提供了与Maven 3.x的完全兼容性。
project xmlnshttp://maven.apache.org/POM/4.1.0 xmlns:xsihttp://www.w3.org/2001/XMLSchema-instancexsi:schemaLocationhttp://maven.apache.org/POM/4.1.0 http://maven.apache.org/xsd/maven-4.1.0.xsdparentgroupIdcom.test/groupIdversion1.0.0/versionartifactIdparent/artifactId/parentgroupIdcom.test/groupIdartifactIdbom/artifactIdversion1.0.0/versionpackagingbom/packagingpropertiesproject1Version1.0.0/project1Versionproject2Version1.0.0/project2Version/propertiesdependencyManagementdependenciesdependencygroupIdcom.test/groupIdartifactIdproject1/artifactIdversion${project1Version}/version/dependencydependencygroupIdcom.test/groupIdartifactIdproject2/artifactIdversion${project2Version}/version/dependency/dependencies/dependencyManagement/project