Maven的依赖管理可以分为以下几个部分:
1. 依赖范围
2. 依赖传递
3. 依赖调解
4. 可选依赖
5. 依赖排除
6. 依赖优化
首先,我们看一下在pom中,对依赖管理的配置结构
<dependency> <!--坐标--> <groupId/> <artifactId/> <version/> <!--附属构件名称,即相同三维坐标下还存在不同的构件时,使用它来区分。比如某构件坐标有:json-lib-2.2.2-jdk13.jar,json-lib-2.2.2-jdk15.jar两个地址,这时使用附属构件名称jdk15来区分--> <classifier/> <!--依赖范围,有compile,runtime,test,system,provided,缺省compile--> <scope/> <!--仅对scope范围是system的构件有效,定义该构件在本地文件系统中的绝对路径--> <systemPath/> <!--排除传递性依赖的构件--> <exclusions> <exclusion> <artifactId/> <groupId/> </exclusion> </exclusions> <!--是否为可选依赖(仅在传递性依赖计算时生效),缺省false--> <optional/> </dependency>
依赖范围 scope
我们知道Maven在编译,测试,运行时会使用不同的classpath,因为不同资源在不同阶段不一定是必须的。比如 junit ,在编译,测试阶段是需要的,但运行期却不需要;servlet-api.jar 在编译,测试阶段是有效的,但运行期容器(如tomcat)已经提供了。依赖范围就是控制依赖在三种classpath中的行为:
1. compile : 编译依赖范围,缺省值。该范围对编译,测试,运行三种classpath都有效。
2. test : 测试依赖范围。只对编译测试代码和运行测试时有效,在编译主代码和运行项目时,是无法使用此类依赖的。
3. provided : 已提供依赖范围。在编译,测试的classpath有效,但运行时无效,如servlet-api。
4. runtime : 运行时依赖范围。对测试classpath有效,但编译主代码时无效。如JDBC驱动实现,在编译阶段只需要使用JDK提供的JDBC接口,只有在运行项目时才会加载。
5. system : 与provided范围一致,但需要指定systemPath。由于依赖本地文件系统,不推荐。
依赖传递
在使用依赖时,Maven会使用依赖传递性规则帮助我们下载依赖的依赖。比如声明依赖A, A又依赖于B, B依赖于C,记为 A -> B, B -> C, 此时,A对B称为第一直接依赖,B对C为第二直接依赖,A -> C为传递性依赖。
所以,我们可以在pom中仅声明依赖A,B和C的依赖关系就会相应地加载过来。注意,并不是所有范围的依赖都可以加载的,只有满足下图关系时,依赖才得以传递:
左边第一列为第一直接依赖,上方第一行为第二直接依赖,交点为依赖传递性:
从上图可以看出:
1. 当第二直接依赖范围为 compile 时,依赖得以传递。
2. 当第二直接依赖范围为 test 时,依赖无法传递(即依赖包无法加载到项目中)。
3. 当第二直接依赖范围为 provided 时,只有第一直接依赖也是 provided 时才得以传递。
4. 当第二直接依赖范围为 runtime 时,依赖得以传递(除第一直接依赖为 compile 外)。
举例来说,假设我们在 pom.xml 中声明依赖A[scope=compile], 其中A又依赖于B[scope=runtime],B又依赖于C,我们称A为第一直接依赖,B为第二直接依赖,则C得以传递,范围为runtime。
依赖调解
假设项目有如下的依赖关系:
A -> B -> C -> X(v1.0),A -> D -> X(v2.0)
X是A的传递性依赖,两条路径上X的深度与版本是不一样的。Maven的依赖调解将根据以下规则进行调解,选择合适的X:
1. 最短路径优先
2. 当路径长度一致时,最先声明优先
如上例,X(v2.0) 因为路径较短,得到依赖传递关系。
可选依赖 optional
假设 A -> B, B -> X(可选), B -> Y(可选),因为X,Y都是可选依赖,所以即使A,B范围都是compile,依赖也不会传递。如果要使X, Y依赖生效,只能显式声明。
依赖排除
假设A -> B, B -> C(snapshot),在A项目发布时(snapshot -> release),因为传递依赖C可能是不稳定版本(或某些原因你不想使用C),这时可以通过 exclusions 排除C的依赖传递,而显示声明稳定版本。
依赖优化
通过Maven处理后的依赖,包括直接依赖与传递依赖,统称为已解析依赖(Resolved Dependency)。
我们可以使用下面的工具分析与优化依赖:
1. mvn dependency:list
2. mvn dependency:tree
3. mvn dependency:analyze
参考
http://maven.apache.org/ref/3.3.3/maven-model/maven.html
http://maven.apache.org/guides/introduction/introduction-to-optional-and-excludes-dependencies.html
Maven实战 - 许晓斌
相关推荐
Maven 是 Apache 软件基金会的一个关键项目,它是一个项目管理和综合工具,主要用于Java应用程序的构建、依赖管理和项目信息管理。Maven 的核心理念是通过一个标准化的构建生命周期来简化软件开发流程,它通过读取...
Maven的依赖管理是其强大功能之一。通过在POM文件中声明项目所依赖的库,Maven会自动下载这些依赖并管理它们,避免了类路径冲突。Maven的中央仓库包含了大量的开源项目,几乎可以找到大部分常见的Java库。 在安装...
Maven的核心功能是依赖管理。它通过POM.xml文件管理项目的依赖关系,自动下载所需的JAR包并解决依赖冲突。此外,Maven还提供了生命周期(Lifecycle),如`clean`、`compile`、`test`、`package`、`install`和`deploy...
Apache Maven 是一个强大的项目管理工具,广泛用于Java应用程序的构建、管理和依赖管理。Maven 3.9.6 是该工具的一个稳定版本,提供了一系列改进和优化,旨在提高开发效率和构建过程的可靠性。 Maven 使用一个约定...
8. **maven-aether-provider**:Aether库是Maven用来处理依赖管理的部分,它负责从远程仓库下载和管理依赖。 9. **maven-artifact-manager** 和 **maven-repository-metadata**:这两个模块处理与Maven仓库的交互,...
Maven通过其强大的依赖管理功能,使得项目构建变得简单和规范。而Jetty作为轻量级服务器,启动速度快,适合开发和调试阶段。将两者结合,开发者可以在Maven构建流程中直接启动和测试Web应用,无需额外的服务器配置...
Apache Maven 是一个强大的Java项目管理和综合工具,它简化了构建过程,通过标准化构建生命周期和依赖管理,使得开发者能够更高效地构建、测试和部署Java应用程序。Maven 3.3.9是Maven的一个稳定版本,它包含了多个...
Apache Maven 是一个强大的Java项目管理和综合工具,它基于项目对象模型(Project Object Model,POM)的概念,使得构建、依赖管理和文档生成变得简单。Maven 3.8.4是该工具的一个稳定版本,提供了多项改进和修复,...
Apache Maven 是一个强大的项目管理工具,它主要用于Java项目的构建、依赖管理和项目信息管理。Maven 3.5.3是该工具的一个稳定版本,提供了许多改进和修复,以提升开发人员的工作效率。在这个版本中,我们可以看到...
- **依赖管理**: 在POM.xml中声明项目依赖,Maven会自动解决依赖关系,从仓库下载并管理它们。 - **插件**: Maven的扩展性主要体现在插件上,如`maven-compiler-plugin`用于编译Java代码,`maven-surefire-plugin`...
6. 依赖管理:Maven的依赖管理允许项目声明所依赖的其他库,并自动解决依赖关系。Maven会根据版本管理和传递性依赖的原则,自动下载并管理这些库。 7. settings.xml配置:在Maven的配置文件settings.xml中,可以...
例如,我们可以指定源代码编码、JRE版本、是否自动导入Maven依赖到Eclipse的类路径等。下面是一个基本的配置示例: ```xml ... ... <groupId>org.apache.maven.plugins <artifactId>maven-eclipse-...
Maven-Helper 插件是 IntelliJ IDEA 中的一款功能强大且实用的插件,旨在帮助开发者更好地管理 Maven 项目的依赖关系。下面是 Maven-Helper 插件的主要知识点: 1. 依赖关系查看:Maven-Helper 插件提供了一个简洁...
Apache Maven 是一个强大的Java项目管理工具,它基于项目对象模型(Project Object Model,POM)的概念,能够自动化构建、依赖管理和项目信息管理。Maven 3.5.4是Maven的一个稳定版本,包含了多项改进和修复,为...
总之,Apache Maven 3.6.0作为一款强大的Java项目管理工具,提供了自动化构建、依赖管理和项目信息管理等功能,极大地提高了开发效率。通过合理的配置和使用,开发者可以更专注于编写代码,而非构建流程。
Maven的依赖管理不仅处理项目间的依赖,还通过传递性依赖解决了依赖树中的冲突问题。此外,Maven可以通过聚合项目(aggregation)功能管理多个模块项目,使得大型多模块项目构建变得简单。 总之,`apache-maven-...
maven是个项目管理工具,如果我们不告诉它我们的代码要使用什么样的jdk版本编译的话,它就会用maven-compiler-plugin默认的jdk版本来进行处理,这样就容易出现版本不匹配,以至于可能导致编译不通过的问题。...
4. **依赖管理**:Maven使用传递性依赖管理,如果项目A依赖于项目B,而项目B又依赖于项目C,那么在构建项目A时,Maven会自动下载项目B和C的依赖。 5. **多模块项目**:对于大型项目,Maven支持多模块构建,可以在一...
总的来说,Apache Maven 3.6.3作为一款流行的Java构建工具,其强大的依赖管理和标准化的构建流程,极大地提高了开发效率和项目的可维护性。通过正确配置和使用,可以有效地管理复杂的项目结构和依赖关系。
在Java开发中,Maven已经成为了不可或缺的一部分,特别是在大型项目中,它的依赖管理和构建功能尤为关键。 `apache-maven-3.6.2-bin.tar.gz` 是Apache Maven 3.6.2版本的二进制发行版,以tar.gz格式打包。这个...