JAVA语言之解析Maven依赖机制

JAVA语言之解析Maven依赖机制 依赖传递依赖相关命令mvn dependency:list查看当前项目所有依赖。mvn dependency:tree以树的形式显示当前项目的所有依赖相比mvn dependency:list 列表显示能很清楚的看到某个依赖是通过哪条依赖路径引入的。mvn dependency:analyze分析项目的依赖关系并确定哪些依赖是使用和声明、使用和未声明、未使用和声明。依赖的传递性如有依赖关系为A-B-CA依赖B称为直接依赖。A本身不依赖C但C通过B传递给A称C为A的传递性依赖。通过mvn dependency:list查看A项目的依赖列表可以看到依赖B和C[INFO] --- maven-dependency-plugin:2.8:list (default-cli) A ---[INFO][INFO] The following files have been resolved:[INFO] com.nocoffee:B:jar:0.0.1-SNAPSHOT:compile[INFO] junit:junit:jar:3.8.1:test[INFO] com.nocoffee:C:jar:0.0.1-SNAPSHOT:compile[INFO][INFO] ------------------------------------------------------------------------[INFO] BUILD SUCCESS[INFO] ------------------------------------------------------------------------依赖调解场景1路径1A-B-C(version:1.0)路径2A-D-E-C(version:2.0)通过两条依赖路径可以看出A的传递性依赖的C有两个不同版本为了避免依赖重复最终只能选择一个。这种情况Maven采用路径最近者优先的原则来处理路径1中C到A的距离比路径2中C到A的距离要短于是路径1中C(version:1.0)最终被A依赖。mvn dependency:tree 查看依赖路径[INFO] --- maven-dependency-plugin:2.8:tree (default-cli) A ---[INFO] com.nocoffee:A:jar:0.0.1-SNAPSHOT[INFO] - com.nocoffee:B:jar:0.0.1-SNAPSHOT:compile[INFO] | \- com.nocoffee:C:jar:0.0.1-SNAPSHOT:compile[INFO] | \- com.nocoffee:D:jar:0.0.1-SNAPSHOT:compile[INFO] | \- com.nocoffee:E:jar:0.0.1-SNAPSHOT:compile[INFO] \- junit:junit:jar:3.8.1:test[INFO] ------------------------------------------------------------------------[INFO] BUILD SUCCESS[INFO] ------------------------------------------------------------------------场景2路径1A-B-C(version:1.0)路径2A-D-C(version:2.0)路径1和路径2中C到A的距离是相同的通过路径最近者优先原则无法判断该使用哪个依赖此时Maven会使用第一声明者优先原则进行选择第一声明者优先原则是指在POM依赖中声明顺序最靠前的那个依赖会被选择。在A的POM文件中B的声明靠前于是C(version:1.0)会被选择。!-- A的pom.xml中依赖部分--dependenciesdependencygroupIdcom.nocoffee/groupIdartifactIdB/artifactIdversion0.0.1-SNAPSHOT/version/dependencydependencygroupIdcom.nocoffee/groupIdartifactIdD/artifactIdversion0.0.1-SNAPSHOT/version/dependencydependencygroupIdjunit/groupIdartifactIdjunit/artifactIdversion3.8.1/versionscopetest/scope/dependency/dependenciesmvn dependency:tree 查看依赖路径[INFO] --- maven-dependency-plugin:2.8:tree (default-cli) A ---[INFO] com.nocoffee:A:jar:0.0.1-SNAPSHOT[INFO] - com.nocoffee:B:jar:0.0.1-SNAPSHOT:compile[INFO] | \- com.nocoffee:C:jar:0.0.1-SNAPSHOT:compile[INFO] - com.nocoffee:D:jar:0.0.1-SNAPSHOT:compile[INFO] \- junit:junit:jar:3.8.1:test[INFO] ------------------------------------------------------------------------[INFO] BUILD SUCCESS[INFO] ------------------------------------------------------------------------排除依赖在场景2中如果要使A依赖C(version:2.0) 则可以配置排除依赖dependenciesdependencygroupIdcom.nocoffee/groupIdartifactIdB/artifactIdversion0.0.1-SNAPSHOT/versionexclusions!-- 排除依赖 C --exclusiongroupIdcom.nocoffee/groupIdartifactIdC/artifactId/exclusion/exclusions/dependencydependencygroupIdcom.nocoffee/groupIdartifactIdD/artifactIdversion0.0.1-SNAPSHOT/version/dependencydependencygroupIdjunit/groupIdartifactIdjunit/artifactIdversion3.8.1/versionscopetest/scope/dependency/dependenciesmvn dependency:tree 查看依赖路径A不再通过B依赖C而是通过D依赖C[INFO] --- maven-dependency-plugin:2.8:tree (default-cli) A ---[INFO] com.nocoffee:A:jar:0.0.1-SNAPSHOT[INFO] - com.nocoffee:B:jar:0.0.1-SNAPSHOT:compile[INFO] - com.nocoffee:D:jar:0.0.1-SNAPSHOT:compile[INFO] | \- com.nocoffee:C:jar:0.0.1-SNAPSHOT:compile[INFO] \- junit:junit:jar:3.8.1:test[INFO] ------------------------------------------------------------------------[INFO] BUILD SUCCESS[INFO] ------------------------------------------------------------------------可选依赖可以将某个依赖配置为可选依赖则该依赖不会参与依赖传递。以场景2为例可以在B的pom.xml里将C配置为可选依赖使A依赖D的C(version:2.0)。!-- B的pom.xml --dependencygroupIdcom.nocoffee/groupIdartifactIdC/artifactIdversion0.0.1-SNAPSHOT/version!-- 设置可选依赖 --optionaltrue/optional/dependencymvn dependency:tree 查看依赖路径A不再通过B依赖C而是通过D依赖C[INFO] --- maven-dependency-plugin:2.8:tree (default-cli) A ---[INFO] com.nocoffee:A:jar:0.0.1-SNAPSHOT[INFO] - com.nocoffee:B:jar:0.0.1-SNAPSHOT:compile[INFO] - com.nocoffee:D:jar:0.0.1-SNAPSHOT:compile[INFO] | \- com.nocoffee:C:jar:0.0.1-SNAPSHOT:compile[INFO] \- junit:junit:jar:3.8.1:test[INFO] ------------------------------------------------------------------------[INFO] BUILD SUCCESS[INFO] ------------------------------------------------------------------------依赖范围Maven在编译、测试、运行时都会使用不同的classpath依赖范围是用来控制依赖和三种classpath的关系。依赖范围介绍1.compile编译依赖范围默认使用该依赖范围在所有classpath中都可用并且依赖项将传播到依赖项目。2.provided已提供依赖范围只对于编译和测试classpath有效运行时无效如Servlet API此范围不具有传递性。3.runtime运行时依赖范围只对于测试和运行classpath有效但在编译主代码时无效。4.test测试依赖范围只对于测试的classpath有效仅适用于测试编译和执行阶段如junit。此范围不具有传递性。5.system系统依赖范围该依赖于三种classpath的关系和provided依赖范围完全一致。区别在于system依赖范围必须通过systemPath元素显示的指定依赖文件的路径。6.import导入依赖范围该依赖范围不会对三种classpath产生影响只有在部分中的pom类型依赖项才支持此范围它指示要替换为指定POM的部分中的有效依赖项列表的依赖项。由于它们被替换具有导入范围的依赖项实际上不参与限制依赖项的传递性。依赖范围对依赖传递的影响每个范围import导入依赖范围除外以不同方式影响传递依赖性如下表所示。以A-B-C依赖路径为例左边第一列为第一直接依赖(B在A中的依赖范围)最上面一行为第二直接依赖(C在B中的依赖范围)交叉单元格为传递性依赖范围(C在A中的依赖范围)。文章来源网络 版权归原作者所有上文内容不用于商业目的如涉及知识产权问题请权利人联系小编我们将立即处理