《Maven实战》学习总结(三)——坐标与依赖管理

       从本篇开始,我们开始接触、熟悉一个概念——“构件”,“在Maven的世界中,任何一个依赖、插件或者项目构建的输出,都可以称为构件。”也就是我们平时所说的jar包、war包、ear包等都可以称为构件。在Maven中,构件的逻辑表现形式是坐标、物理表现形式是“仓库”中的文件。本篇主要介绍Maven坐标的内容以及对项目引用其他构件的处理情况。

Maven坐标(Coordinate)

        “Maven定义了这样一个规则:java世界中任何一个构件都可以使用Maven坐标唯一标识”

        在开发自己的项目的时候,也要定义坐标,这是Maven强制要求的。也由此其他项目才能够引用该项目生成的构件。

        Maven坐标包含以下元素:

              必选项

                      groupId:当前Maven项目隶属的实际项目,一个实际项目可能会对应多个Maven项目(模块)。
                                        与java包名表示类似,与域名反向一一对应

                      artifactId:实际项目中的一个Maven项目(模块)。

                                    推荐做法:使用实际项目名作前缀,方便寻找实际构件       

                     version:当前所处版本


                可选项

                        packaging:定义打包方式,通常与生成构件扩展名对应,默认值为jar

                        classifier:帮助定义构件输出的一些附属构件,不能直接定义(由附加插件帮助生成)


依赖(Dependency)管理

       java项目中我们会引用很多其他的项目,这些项目以jar、war、ear包等类似的形式加入到我们项目(准确的说是添加到classpath)中来,从而我们可以使用期提供的功能,这些我们引用的项目称为依赖。在没有Maven之前,我们不得不下载各个项目的打包文件,将这些放到我们的项目中,这样既费时又费力,而且容易造成各个依赖的版本冲突。而基于Maven坐标,Maven提供的依赖管理功能很大程度上解决了这些问题。

        在Maven项目中,我们要添加依赖,需要做的仅仅是在pom文件中添加类似如下配置即可(具体事例可参考

《Maven实战》学习总结(二)——最基础练习

  <dependencies>  
    <dependency>  
      <groupId>junit</groupId>  
      <artifactId>junit</artifactId>  
      <version>4.7</version>  
      <scope>test</scope>  
    </dependency>  
  </dependencies> 

             以上一条简单的配置就是将junit的jar文件引入了我们的项目中。如果引用多个构件,在dependencies节点下添加多个dependency子节点即可。

配置详解

             必选项

                   groupId、artifactId、version:唯一确定一个依赖构件

              可选项

                    (1)type:依赖类型,对应坐标中packaging,同样默认为jar

                   (2)scope:依赖范围,控制依赖加入到哪些classpath下

                              三种classpath--编译项目主代码、(编译、执行)测试、运行
                                   配置值:
                                        compile(默认):三种classpath都有效
                                      test:测试classpath有效(JUnit)
                                       provided:编译、测试下的classpath有效(servlet-api)
                                       runtime: 测试、运行有效(JDBC接口与驱动)
                                        system:系统依赖范围,与provided情况一样,但与本机系统绑定,不建议使用
                                       import:导入依赖范围,不会对三种classpath产生影响,后面的文章会进行说明

                   (3)optional:依赖是否可选

                           当第一直接依赖的项目实现了不同特性,这些特性之间互斥,(不会同时出现)时可标注:

                                 <optional>true</optional>

                          可选依赖不被传递,因此在目标项目中需要显示声明对应要使用特性所需要的依赖。

                    (4)exclusions:排除传递性依赖

                           

                            项目A依赖于项目B,项目B依赖于项目C,出于某些原因,我们不需要C被传递,而是要显示声明

传递性依赖

       顾名思义,传递性依赖即为“依赖的依赖”,也就是说我们项目的一个依赖很可能也依赖其他构件(我们项目-->依赖构件-->其他构件),这时候,这个“其他构件”很可能也会成为我们项目的依赖。为什么说“很可能”,因为传递性依赖能不能成立还需要看中间两个直接依赖的依赖范围的情况。

     

       A对于B是第一直接依赖,B对于C是第二直接依赖,A对于C是传递性依赖。

      也就是说,现在的问题是:我们我们需要明确这里的传递性依赖的依赖范围是什么?这样我们才能确定这个依赖会引入到哪种classpath下,对我们的程序具体会产生怎样的影响。

     

        上图为由第一直接依赖、第二直接依赖组合决定的传递性依赖情况(“-”代表不会出现传递性依赖)。


       优点:简化了依赖的声明、一般只关心第一直接依赖,不必理会传递性依赖。

        缺点:此机制可能导致依赖版本冲突的问题。对于此Maven的依赖调解(Dependency Mediation)机制给出了Maven的解析原则:近者优先。

                 ①A-->B-->C-->X(5.0)    A-->D--X(4.0)    ——路径:前者为3,后者为2,则4.0会被A所依赖

                 ②A-->B-->Y(6.0)          A-->C-->Y(7.0)    ——声明:当路径相同时,POM文件中声明靠前者会传递

常用命令

       mvn dependency:list            ——查看当前项目的已解析依赖(Resolved Dependency:Maven根据自身规则调整后的依赖关系)

       mvn dependency:tree          ——查看当前项目的依赖解析树,可查看某项依赖的具体解析路径。

       mvn dependency:analyze     ——帮助分析出项目中有必要直接引入、有可能无用的依赖 等功能。


Maven小结

       本篇文章主要介绍Maven中构件的逻辑表示方式——坐标,以及基于此的Maven项目依赖管理功能。分析了依赖的配置、传递性依赖的概念、优点、缺点以及一些常用命令,相信有了这些基础,可以应对项目中依赖的相关应用及使用问题。下篇我们将介绍构件的物理管理方式——仓库。

发布了159 篇原创文章 · 获赞 225 · 访问量 21万+

猜你喜欢

转载自blog.csdn.net/lyg673770712/article/details/50768051
今日推荐