pom.xml 文件解析

一、pom 简介:

        pom 的英文全拼为 Project Object Model ,项目对象模型。通过 xml 可扩展标记语言格式保存 pom.xml 文件,功能更强大。该文件可用于管理:源代码、配置文件、开发者的信息和角色、问题追踪系统、组织信息、项目授权、项目的 url 、项目的依赖关系等。

        一个完整的 pom.xml 文件,放置在项目的根目录下,包含的具体内容如下所示:


  4.0.0
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  

二、基本信息设置:

1、头标签信息:

        粘来即用,关于这三个标签的详细说明可以参考这篇博文《XML文档中的xmlns、xmlns:xsi和xsi:schemaLocation理解》


标签名称 标签解释
xmlns 命名空间,类似包名,因为 xml 的标签可以自定义,需要命名空间来定位
xmlns:xsi xml 需要遵循的标签规范
xsi:schemaLocation 用来定义xml schemaLocation 的地址,也就是 xml 书写时需要遵循的语法

2、maven 的基本信息

        其中 groupIdartifactIdversionpackaging 这四项组成了项目的唯一坐标,一般情况下,前面的三项足矣。


	
  	4.0.0
  	com
  	SpringBoot
  	0.0.1-SNAPSHOT
  	jar
    myName
    www.funtl.com
标签名称 标签解释
modelVersion 声明项目描述遵循哪一个 POM 模型版本。模型本身的版本很少改变,虽然如此,但他仍然是必不可少的,这是为了当 Maven 引入新的特性或者其他模型变更的时候,确保稳定性。
groupId 公司或组织的唯一标识,并且配置时生效的路径也是由此生成,如 com.winner.trademaven 会将项目打成的 jar 包放本地路径:/com/winner/trade 下。
artifactId 本项目的唯一 ID ,一个 groupId 下面可能有多个项目,就是靠 artifactld 来区分的。 
version 本项目目前所处的版本号
packaging 打包类型,可取值:pomjarwarejbparrarearmaven-plugin
name 项目的名称,maven 产生的文档需要用到,可省略
url 项目主页的 url maven 产生的文档需要用到,可省略

3、POM 之间的关系:

        主要是用于 pom 文件之间的复用关系和依赖关系。

3.1、依赖关系 - 依赖关系列表

        该元素描述了项目相关的所有依赖。这些依赖组成了项目构建过程中的一个个环节。它们自动从项目定义的仓库中下载。

 
    
      junit
      junit
      4.0
      test
      true
      
      	  
          xxx
          xxx
        
      
    
标签名称 标签解释
groupId 依赖项的组织名
artifactId 依赖项的子项目名
version 依赖项的版本
type 依赖类型一般省略,默认类型是 jar,其他还有 jarwarejb-clienttest-jar
scope 依赖项的适用范围 ,包括 compileprovidedruntimetestsystem exclusions 
optional 可选依赖,如果你在项目 B 中把 C 依赖声明为可选,你就需要在依赖于 B 的项目(例如项目 A )中显式的引用对 C 的依赖。
exclusions 排除项目中的依赖冲突时使用,不依赖该项目

3.1.1、scope 依赖项的适用范围:

        1、compile:缺省值,适用于所有阶段,会随着项目一起发布。

        2、provided:类似于 compile,期望 JDK、容器或使用者会提供这个依赖,如:servlet.jar

        3、runtime:只在运行时使用,如 JDBC 驱动,不会随项目发布。

        4、system:类似 provided,需要显示提供包含依赖的 jarMaven不会在 Repository 中查找它。

        5、optional:当项目自身被依赖时,标注依赖是否传递,用于连续依赖时使用。

        我们都知道,maven 的依赖关系是有传递性的。如:A -> BB -> C。但有时候,项目 A 可能不是必须依赖 C,因此需要在项目 A 中排除对 C 的依赖,在 maven 的依赖管理中,有两种方式可以对依赖关系进行管理。分别是可选依赖Optional Dependencies)以及依赖排除Dependency Exclusions)。

3.1.2、可选依赖

        当一个项目 A 依赖另一个项目 B 时,项目 A 可能用到了项目 B 很少一部分功能,此时就可以在 A 中配置对 B 的可选依赖。举例来说,项目 B 类似 hibernate,它支持对 mysqloracle 等各种数据库的支持。但是在引用这个项目时,我们可能只用到其对 mysql 的支持,此时就可以在 A 项目中配置对项目 B 的可选依赖。

        配置可选依赖的原因:1、节约磁盘、内存等空间;2、避免 license 许可问题;3、避免类路径问题,等等。

        示例代码如下:


  ...
  
    
    
      sample.ProjectB
      Project-B
      1.0
      compile
      true 
    
  

        假设以上配置是项目 A 的配置,即项目 A 依赖于项目 B。在编译项目 A 时,是可以正常通过的。 如果有一个新的项目 C 依赖项目 A,即 C 依赖于 AA 依赖于 B,此时项目 C 就不会依赖项目 B 了。如果项目 C 用到了涉及项目 B 的功能,那么就需要在 pom.xml 中重新配置对项目 B 的依赖。

3.1.3、依赖排除

情况一:

        当一个项目 A 依赖项目 B,而项目 B 同时依赖项目 C,如果项目 A 中因为各种原因不想引用项目 C,在配置项目 B 的依赖时,可以排除对 C 的依赖。

        假设配置的是项目 A pom.xml,依赖关系为:A 依赖 BB 依赖 C。示例代码如下:


  ...
  
    
      sample.ProjectB
      Project-B
      1.0
      compile
      
          
          sample.ProjectC
          Project-C
        
       
    
  

        当然,对于多重依赖,配置也很简单,参考如下示例,假设 A 依赖于BB 依赖于 DD 依赖于 EE 依赖于 FF 依赖于 CA 对于 E 相当于有多重依赖,我们在排除对 E 的依赖时,只需要在配置 B 的依赖中进行即可:


  4.0.0
  sample.ProjectA
  Project-A
  1.0-SNAPSHOT
  jar
  ...
  
    
      sample.ProjectB
      Project-B
      1.0-SNAPSHOT
      
        
          
          sample.ProjectE 
          Project-E
        
      
    
  

情况二:

        如果我们的项目有两个依赖项:A & B,而且 AB 同时依赖了 C,但 C 不是同一个版本。那么我们怎么办呢?

        首先我们需要添加检查插件,代码如下所示,添加代码之后,运行:mvn project-info-reports:dependencies,来查看依赖项报告。


	
		
			org.apache.maven.plugins
			maven-project-info-reports-plugin
		
	

        然后我们去除依赖项,代码如下所示:


      org.apache.struts
      struts2-core
      ${struts.version}
      
          
              org.freemarker
              freemarker
          
      

3.2、继承关系 - 继承其他 pom.xml 配置的机制

        在我们已经聚合的项目中,有很多重复的配置,有相同的 groupId version,有相同的spring-corespring-beansspring-context juit 依赖,造成大量的浪费也会引发问题,所以如何使用继承机制来统一配置这些重复的信息,做到 ” 一处声明,处处使用 “ 呢?

        这个时候就需要创建 pom 的父子结构,在父 pom 中声明一些配置供子 pom 继承。

        父 pom.xml 的内容如下所示:


  [...]
  
    
      junit
      junit
      4.4
      test
    
  
  [...]

         子 pom.xml 的内容如下所示,relativePath 默认为 …/pom.xml,如果路径不一样需要手动指定。

[...]

  com.devzuz.mvnbook.proficio
  proficio
  1.0-SNAPSHOT
  ../ParentProject/pom.xml   

[...]

3.3、聚合关系 - 用于将多个 maven 项目聚合为一个大的项目

        我们想要一次构建两个项目,而不是到两个模块的目录下分别执行 mvn 命令 – Maven 的聚合就是为该需求服务的。为了能够使用一条命令就能构建 account-email account-persist 两个模块,需要创建一个额外的名为 account-aggregator 的模块,然后通过该模块构建整个项目的所有模块。

        account-aggregator 项目的 pom.xml 的内容如下所示:


    4.0.0
    com.park.mvnDemo.account
    account-aggregator
    1.0.0-SNAPSHOT
    pom
    Account Aggregator
    
        account-email
        account-persist
    

        在上面的 xml 文件中,packaging 的方式为 pom。对于聚合模块来说, 其打包方式必须为pom,否则无法构建!

        modules:这里是实现聚合的最核心的配置,可以声明任意数量的 module 元素来实现元素的聚合;其中,每个 module 的值为当前聚合 pom 相对路径

        如:当前的聚合 pom 位于 D:\m2\code\account-aggregator\ ,项目 A 位于D:\m2\code\account-aggregator\account-email\,一个项目 B 位于 D:\m2\code\-aggregatoraccount\account-persist\,与上面聚合 pom 内的的 module 值相对应。也可写成 /account-email。

        为了方便用户构建项目,通常将聚合模块放在项目目录的最顶层,其他模块则作为聚合模块的子目录存在。当然,你也可以手动指定路径。

4、Maven 的六类属性:

4.1、maven 内置属性

        主要有两个常用内置属性,如下所示:

标签名称 标签解释
${basedir} 项目的根目录(包含 pom.xml 文件的目录)
${version} 项目版本

4.2、pom 属性

        用户可以使用该属性引用 pom 文件中对应元素的值,常用的 pom 属性包括:

标签名称 标签解释
${project.build.sourceDirectory} 项目的主源码目录,默认为 src/main/java
${project.build.testSourceDirectory} 项目的测试源码目录,默认为 src/test/java
${project.build.directory} 项目构件输出目录,默认为 target/
${project.outputDirectory} 项目主代码编译输出目录,默认为 target/classes/
${project.testOutputDirectory} 项目测试代码编译输出目录,默认为 target/test-classes/
${project.groupId} 项目的 groupId
${project.artifactId} 项目的 artifactId
${project.version} 项目的 version,与 ${version} 等价
${project.build.fianlName} 项目打包输出文件的名称,默认为 " ${project.artifactId} - ${project.version} "

4.3、自定义属性

        用户可以在 pom 的元素下自定义 Maven 属性,示例代码如下,然后我们可以在 pom 文件中通过 ${zipkin.version} 来使用他们。

 
 
     
     1.8
     UTF-8
     UTF-8

     
     Finchley.RELEASE
     2.0.1
     2.10.1
 

4.3.1 dependencies 和 dependencyManagement 标签:

        在通常情况下,由于我们的模块很多,我们需要一个 itoken-denpendencies 的项目来管理子项目的公共的依赖。为了项目的正确运行,必须让所有的子项目使用依赖项的统一版本,必须确保应用的各个项目的依赖项和版本一致,才能保证测试的和发布的是相同的结果。

        在我们项目顶层的 pom 文件中,我们会看到 dependencyManagement 元素。通过它元素来管理 jar 包的版本,让子项目中引用一个依赖而不用显示出具体的版本号。结合 maven 的自定义属性,我们来看看项目中的具体应用:

        下面是 itoken-denpendencies 中的 pom.xml ,在父项目中用 dependencyManagement 声明依赖的版本:


	
	    
	    
	        org.springframework.cloud
	        spring-cloud-dependencies
	        ${spring-cloud.version}
	        pom
	        import
	    
	    
	    
	        io.zipkin.java
	        zipkin
	        ${zipkin.version}
	    
	    [...]
	
            

        在子项目中,Maven 会沿着父子层次向上走,直到找到一个拥有 dependencyManagement 元素的项目,然后它就会使用在这个 dependencyManagement 元素中指定的版本号。 itoken-zipkin 中的 pom.xml 内容如下所示:


    
    
        org.springframework.cloud
        spring-cloud-dependencies
    
    
    
        io.zipkin.java
        zipkin
    
    [...]

        需要注意的是,dependencyManagement 里只是声明依赖,并不实现引入。如果不在子项目中声明依赖,是不会从父项目中继承下来的;只有在子项目中写了该依赖项,并且没有指定具体版本,才会从父项目中继承该项,并且 version scope 都读取自父 pom。如果子项目中指定了版本号,那么会使用子项目中指定的 jar 版本。

4.4、Settings 属性

        用户使用 ${settings.} 开头的属性可以引用 maven settings.xml 文件中 xml 元素的值,如下所示:

标签名称 标签解释
settings.localRepository 自定义本地库路径,默认在 ${user.home}/.m2
settings.interactiveMode 交互模式,Maven 是否应该尝试与用户输入交互,默认是 true,如果不是 false
settings.offline 是否每次编译都去查找远程中心库, 如果此构建系统应以离线模式运行,则为 true,默认为 false。由于网络设置或安全原因,此元素对于构建无法连接到远程存储库的服务器非常有用。
settings.pluginGroups 插件组,例如 org.mortbay.jetty 

4.5、Java系统属性

        所有 Java 系统属性都可以使用 Maven 属性引用,这里列举一些常用的 Java 系统属性。

标签名称 标签解释
java.version Java 运行时环境版本
java.vendor Java 运行时环境供应商
java.vendor.url Java 供应商的 URL
java.home Java 安装目录
java.vm.specification.version Java 虚拟机规范版本
java.vm.specification.vendor Java 虚拟机规范供应商
java.vm.specification.name Java 虚拟机规范名称
java.vm.version Java 虚拟机实现版本
java.vm.vendor Java 虚拟机实现供应商
java.vm.name Java 虚拟机实现名称
java.class.path Java 类路径
os.name 操作系统的名称
file.separator 文件分隔符(在 UNIX 系统中是“/”)
user.name 用户的账户名称
user.home 用户的主目录
user.dir 用户的当前工作目录

4.6、环境变量属性

        所有环境变量都可以使用以 env. 开头的 Maven 属性引用。比如:${env.JAVA_HOME} 表示环境变量的值。

5、构建设置

        build 标签可以是单独的,也可以是包含在 profile 标签里面,如下所示:


  
  
  
    
      
      
    
  

        build 标签包含两个子标签,分别是 Resources 标签和 Plugins 标签,下面分别介绍下这两个标签。

5.1 Resources 标签

        资源文件管理,用于引用或者排除资源文件,如下所示:


	
		META-INF/plexus
		false
		${basedir}/src/main/plexus
		
		  configuration.xml
		
		
		  **/*.properties
		
	

标签名称 标签解释
targetPath 资源的打包路径,该路径相对 target/classes 目录
filtering 主要用来替换项目中的资源文件(* .xml* . properties)当中的 $ {…} 属性值如 $ {db.url} 
如果 filtering=trueresources 目录中存在资源文件并且配置了 db.url=aaa 的话, 
在项目编译的时候,就会自动的把 pom 文件中的 ${db.url} 替换为 aaa
directory 描述存放资源的目录,该路径相对 pom 的路径
includes 包含的模式列表,例如 **/*.xml
excludes 排除的模式列表,例如 **/*.xml

5.2 Plugins 标签

        设置构建的插件,为什么我们需要插件?

        第一个原因是我们需要某个特殊的 jar 包,但是又不能直接通过 maven 依赖获取,或者说在其他环境的 maven 仓库内不存在,那么如何将我们所需要的 jar 包打入我们的生产 jar 包中。就需要这个插件。

        第二个原因是某个 jar 包内部包含的文件是我们所需要的,或者是我们希望将它提取出来放入指定的位置 ,那么除了复制粘贴,也可以通过 maven 插件实现。

5.2.1 plugins 和 pluginmanagement 

        maven 通过 plugins pluginmanagement 来管理插件,类似 dependencies dependencyment 。但需要注意的是,plugins pluginmanagement 隶属于 build 标签下,而不是最外层的 project 标签。

        在父项目中声明插件和版本信息,同样 pluginmanagement 也不会直接引入插件。


    
        
            org.apache.maven.plugins
            maven-source-plugin
            2.1
            
                true
            
            
                
                    compile
                    
                        jar
                    
                
            
        
    

        在子项目中引入插件,同样,子项目继承父项目的 plugin 设置,并可以自由定义。


    
        org.apache.maven.plugins
        maven-source-plugin
    

 6、Maven 仓库配置

        Maven 仓库就是放置所有 JAR 文件(WARZIPPOM 等等)的地方,所有 Maven 项目可以从同一个 Maven 仓库中获取自己所需要的依赖 JAR,这节省了磁盘资源。此外,由于 Maven 仓库中所有的 JAR 都有其自己的坐标,该坐标告诉 Maven 它的组件 ID构件 ID版本打包方式等等,因此 Maven 项目可以方便的进行依赖版本管理。你也不再需要提交 JAR 文件到 SCM 仓库中,你可以建立一个组织层次的 Maven 仓库,供所有成员使用。

        简言之,Maven仓库能帮助我们管理构件(主要是JAR)。maven 寻找仓库的顺序大致可以理解为:

                1、在本地仓库中寻找,如果没有则进入下一步。

                2、在全局应用的私服仓库中寻找,如果没有则进入下一步。

                3、在项目自身的私服仓库中寻找,如果没有则进入下一步。

                4、在中央仓库中寻找,如果没有则终止寻找。

补充:

        1、如果在找寻的过程中,如果发现该仓库有镜像设置,则用镜像的地址代替。

        2、如果仓库的 id 设置成 “ central ” ,则该配置会覆盖 maven 默认的中央仓库配置。

6.1 本地仓库:

        Maven 缺省的本地仓库地址为 ${user.home}/.m2/repository 。也就是说,一个用户会对应的拥有一个本地仓库。你也可以自定义本地仓库的位置,修改 ${user.home}/.m2/settings.xml

D:/repo

        也可以在运行时指定本地仓库位置: 

mvn clean install -Dmaven.repo.local=/home/juven/myrepo/

6.2 中央仓库:

        3.xxx 版本之后,在 maven 安装目录下的:/lib/maven-model-builder-${version}.jar
打开该文件,能找到超级 pom :\org\apache\maven\model\pom-4.0.0.xml,它是所有 Maven  pom父 pom ,所有 Maven 项目继承该配置,你可以在这个 pom 中发现如下配置:

  
    
      central
      Central Repository
      https://repo.maven.apache.org/maven2
      default
      
        false
      
    
  

        中央仓库的 id central,远程 url 地址为 http://repo.maven.apache.org/maven2 ,它关闭了 snapshot 快照版本构件下载的支持。

6.3 在 pom.xml 中配置远程仓库:

        前面我们看到超级 pom 配置了 ID central 的远程仓库,我们可以在 pom 中配置其它的远程仓库。这样做的原因有很多,比如你有一个局域网的远程仓库,使用该仓库能大大提高下载速度,继而提高构建速度,也有可能你依赖的一个 jar central 中找不到,它只存在于某个特定的公共仓库,这样你也不得不添加那个远程仓库的配置。这里我配置一个远程仓库指向中央仓库的中国镜像:


...
  
    
      maven-net-cn
      Maven China Mirror
      http://maven.net.cn/content/groups/public/
      
        true
      
      
        false
      
    
  
  
    
      maven-net-cn
      Maven China Mirror
      http://maven.net.cn/content/groups/public/
      
        true
      
      
        false
          
    
  
...

        我们先看一下它的配置,你可以在它下面添加多个 ,每个都有它唯一的 ID,一个描述性的 name,以及最重要的,远程仓库的 url 。此外:


true   


false

        禁止从公共仓库下载 snapshot 构件是推荐的做法,因为这些构件不稳定,且不受你控制,你应该避免使用。当然,如果你想使用局域网内组织内部的仓库,你可以激活 snapshot 的支持。

你可能感兴趣的:(Maven,maven)