• 后端——工具——构建工具——Maven——第二章节(pom.xml)——待完善


      第二章节开始就是满满的干货,本章介绍pom文件中的内容。知识点分为三个

    1. pom文件的总体结构
    2. super pom
    3. 项目, 自身的标识,关系等。

    1、pom文件

      pom文件的总体结构很复杂,但是经常用到的比较少。它大致分为以下几个部分

    1. 第一部分为与项目有关的信息,它的开发者,组织机构,认证license等等
    2. 第二部分为项目的依赖。
    3. 第三部分为项目的编译过程。
    4. 第四部分为依赖的仓库以及依赖插件的仓库
    5. 第五部分为其他杂项。这些很少用到

    1.1 自身信息

      项目的相关信息包含项目自身的信息,项目的开发人员的相关信息,项目的其他信息。

      项目自身的信息

    <!-- 项目的名称 -->
    <name>childB</name>
    <!-- 项目的描述-->
    <description>childB project for learn pom file constructor
    </description>
    <!-- 项目的url地址 -->
    <url>http://www.example.com</url>
    <!-- 项目的组织机构Id -->
    <groupId>com.learn.maven</groupId>
    <!-- 项目的jar包Id  -->
    <artifactId>childB</artifactId>
    <!-- 项目的版本号 -->
    <version>1.0-SNAPSHOT</version>
    <!-- 项目的打包形式,支持war,jar等等 -->
    <packaging>jar</packaging>
    1. name标签用户指定项目的名称,在创建项目时自动生成
    2. description标签用于指定项目的描述信息。
    3. url标签用于指定项目的url地址
    4. groupId标签用于指定项目的组织机构ID,一般是域名的逆序。它是必填的。
    5. artifactId标签用于指定项目的ID。它是必填的
    6. version标签用于指定项目的版本,它是必填的。
    7. packaging标签用于指定项目打包的形式,经常用到的有pom, war, jar。它是必填的

      项目开发者的信息

    <!-- 项目的开发相关信息 -->
    <!-- 项目的组织机构信息  -->
    <organization>
        <name>com.learn.someBody</name>
        <url>http://www.example.com</url>
    </organization>
    <!-- 项目的开发人员信息  -->
    <developers>
        <developer>
            <name>Jack</name>
            <email>XXX@126.com</email>
        </developer>
        <developer>
            <name>Mike</name>
            <email>XXX@126.com</email>
        </developer>
    </developers>
    <!-- 项目的卓越贡献者-->
    <contributors>
        <contributor>
            <name>somebody</name>
            <email>XXX@126.com</email>
        </contributor>
    </contributors>
    1. organization标签用于指定项目的开发机构
    2. developers标签用于指定项目的开发者
    3. contributors标签用于指定项目的共享者

      项目的其他信息

    1. parent标签用于指定项目的父项目。它属于项目的关系,当建立父子关系项目时,必填。
    2. modelVersion标签用于指定pom文件结构的版本。
    <project xmlns="http://maven.apache.org/POM/4.0.0" 
    	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
             xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 
             http://maven.apache.org/xsd/maven-4.0.0.xsd">

      3.licenses标签用于指定项目的认证信息。

    1.2    依赖

      项目的依赖即项目之间的关系。有两种类型,一种是继承,一种是组合关系。

      继承关系

    1. 若是父项目,使用modules标签指定子项目
    <modules>
        <module>childA</module>
        <module>childB</module>
    </modules>
    

      2.若是子项目,使用parent标签指定父项目。

    <parent>
        <artifactId>parent</artifactId>
        <groupId>org.example</groupId>
        <version>1.0-SNAPSHOT</version>
    </parent>
    

      组合关系

    1. Dependencies标签添加一到多个依赖。经常见,略。
    <dependencies>
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>4.11</version>
            <scope>test</scope>
        </dependency>
    </dependencies>
    

      2.dependencyManagement标签用于在父项目中定义子项目需要继承的依赖。

    <!-- 覆盖父项目中的一到多个依赖 -->
    <dependencyManagement>
        <dependencies>
            <dependency>
                <groupId>junit</groupId>
                <artifactId>junit</artifactId>
                <version>4.10</version>
                <scope>test</scope>
            </dependency>
        </dependencies>
    </dependencyManagement>
    

    1.3  编译

      1.3.1  conversion(约定俗成)

    约定俗成的意思是指项目目录结构约定俗成的规则。

    约定俗成是指主要代码应该放在src/main下面,测试代码应该放在src/test下面。脚本应该放在src/main/scripts下面。

    约定俗成在super pom中有所体现

    <!-- 项目的默认编译路径,项目当前路径/target-->
    <directory>${project.basedir}/target</directory>
    <!-- src/main/java,src/main/resources编译的存放路径-->
    <outputDirectory>${project.build.directory}/classes</outputDirectory>
    <!-- 项目打包的默认名称 -->
    <finalName>${project.artifactId}-${project.version}</finalName>
    <!-- src/test/java,src/test/resources编译的存放路径 -->
    <testOutputDirectory>${project.build.directory}/test-classes</testOutputDirectory>
    <!-- 资源的存放路径 -->
    <sourceDirectory>${project.basedir}/src/main/java</sourceDirectory>
    <!-- 脚本的存放路径 -->
    <scriptSourceDirectory>${project.basedir}/src/main/scripts</scriptSourceDirectory>
    <!-- 测试的存放路径 -->
    <testSourceDirectory>${project.basedir}/src/test/java</testSourceDirectory>
    <!-- 配置资源的定义,包含src/main/resources-->
    <resources>
      <resource>
        <directory>${project.basedir}/src/main/resources</directory>
      </resource>
    </resources>
    <!-- 测试配置资源的定义,包含src/main/resources-->
    <testResources>
      <testResource>
        <directory>${project.basedir}/src/test/resources</directory>
      </testResource>
    </testResources>
    

    1.3.2   Include & exclude规则

      默认情况下, 编译会包含src/main下面所有的资源。可以通过resources指定更小的范围,它的结构为

    <resources>
        <resource>
            <includes></includes>
            <excludes></excludes>
            <directory></directory>
            <filtering>true</filtering>
            <targetPath>/target</targetPath>
        </resource>
    </resources>
    

      Resources包含一到多个resource,指定资源的规则,

    • includes指定包含的资源,例如只想编译特定包下面的资源
    •  excludes指定排除的资源。
    • directory指定资源的存放目录
    • filtering指定是否经过过滤。
    • targetPath指定编译输出的目录。

      1.3.3   打包

      配置finalName标签,指定项目最终打包的名称。

    1.3.4   插件

      TODO。

    1.4     仓库地址

      项目的仓库有两类,一种是依赖jar包的仓库地址,另外一种是依赖插件的仓库地址。

    1. repositories标签用于设置依赖的仓库地址,例如添加阿里的仓库地址
    <!-- 仓库地址 -->
    <repositories>
        <repository>
            <id>nexus-aliyun</id>
            <name>Nexus aliyun</name>
            <layout>default</layout>
         <url>http://maven.aliyun.com/nexus/content/groups/public</url>
            <snapshots>
                <enabled>false</enabled>
            </snapshots>
            <releases>
                <enabled>true</enabled>
                <checksumPolicy>ignore</checksumPolicy>
                <!-- 每天检查,自动更新jar包,在实际中不要设置 -->
                <updatePolicy>daily</updatePolicy>
            </releases>
        </repository>
    </repositories>
    

      2.pluginRepositories标签用于设置插件的仓库地址,它们基本上是同一个

    1.5  报告

      报告是项目生命周期的尾声。它的结构格式如下: 

    <reporting>
        <plugins></plugins>
        <excludeDefaults>true</excludeDefaults>
        <outputDirectory></outputDirectory>
    </reporting>
    
    • Plugins:用于指定生成报告的插件,通常是对应site生命周期,关联默认的插件,无需特别指定。
    • excludeDefaults:生成的报告中是否包含一些默认的信息,例如项目自身的信息。
    • outputDirectory:报告生成之后,指定它们的存放路径。

    1.6  profile

      TODO

    1.7   distributionManagement

      TODO

    1.8      其他

      issueManagement用于管理项目问题追踪,类似于bug平台。

    <issueManagement>
        <!-- 系统的url地址 -->
        <url></url>
        <!-- 系统的名称 -->
        <system></system>
    </issueManagement>
    

      ciManagement用于项目持续更新迭代的地址,ci的全称为continous intergrate。

    <ciManagement>
        <!-- 持续集成系统的名称 -->
        <system></system>
        <!-- 持续集成系统的url地址 -->
        <url></url>
        <!-- 通知的配置 -->
        <notifiers>
            <notifier>
                <!-- 通知的类型 -->
                <type>mail</type>
                <!-- 错误时是否发送通知 -->
                <sendOnError>true</sendOnError>
                <!-- 异常时是否发送通知 -->
                <sendOnFailure>true</sendOnFailure>
                <!-- 正常时是否发送通知 -->
                <sendOnSuccess>false</sendOnSuccess>
                <!-- 警告时是否发送通知 -->
                <sendOnWarning>false</sendOnWarning>
                <!-- 通知的地址 -->
                <address>xx@126.com</address>
            </notifier>
        </notifiers>
    </ciManagement>
    

      mailingList用于指定公开的邮箱列表,主要用于提交使用者的反馈。

    <mailingLists>
        <mailingList>
            <!-- 邮件的名称 -->
            <name></name>
            <!-- 订阅的邮件地址 -->
            <subscribe></subscribe>
            <!-- 不订阅的邮件地址 -->
            <unsubscribe></unsubscribe>
            <!-- 项目每次迭代生成Jar包的url地址 -->
            <archive></archive>
            <!-- 其他可供选择的url地址 -->
            <otherArchives></otherArchives>
            <!-- 当需要反馈时,用户将反馈内容发送到该地址 -->
            <post></post>
        </mailingList>
    </mailingLists>
    

      scm用于指定软件配置管理的功能,全称为software configuration management。类似git, svn之类的系统。

    2、super pom

      pom本质也是一种树形结构,super pom就是树的根。类似于Java中的Object。有效的pom,包含所有父pom以及子pom中存在的项。

      在日常开发中,若没有将项目模块化,项目的pom会直接继承super pom。

      Super pom存在于maven-model-builder-version.jar中,路径为org/apache/maven/model。它的名称为pom-modelVersion.xml。目前使用的modelVersion为4.0.0。

      下面详细介绍super pom的内容

    2.1  自身信息

      项目相关信息中,公共部分极少,在super pom中只有modelVersion。源配置如下:

    <modelVersion>4.0.0</modelVersion>
    

    2.2  依赖

      无

    2.3     仓库地址

      仓库地址有两类,依赖的maven仓库地址,插件的maven仓库地址

      依赖的maven仓库地址, 它默认的仓库地址是maven2,不下载快照版本的依赖

    <repositories>
    	<repository>
    	  <id>central</id>
    	  <name>Central Repository</name>
    	  <url>https://repo.maven.apache.org/maven2</url>
    	  <layout>default</layout>
    	  <snapshots>
    	    <enabled>false</enabled>
    	  </snapshots>
    	</repository>
    </repositories>
    

      插件的maven仓库地址,它默认也是maven2,不下载快照版本,不自动更新

    <pluginRepositories>
    	<pluginRepository>
    	  <id>central</id>
    	  <name>Central Repository</name>
    	  <url>https://repo.maven.apache.org/maven2</url>
    	  <layout>default</layout>
    	  <snapshots>
    	    <enabled>false</enabled>
    	  </snapshots>
    	  <releases>
    	    <updatePolicy>never</updatePolicy>
    	  </releases>
    	</pluginRepository>
    </pluginRepositories>
    

      在这里若要添加阿里云的仓库,可以直接添加到super pom当中。并替换原来jar包中的文件。

    2.4    编译

      编译的内容分为两个部分,编译的路径,编译使用的插件。

      2.4.1   路径

    <!-- 项目的默认编译路径,项目当前路径/target-->
    <directory>${project.basedir}/target</directory>
    <!-- src/main/java,src/main/resources编译的存放路径-->
    <outputDirectory>${project.build.directory}/classes</outputDirectory>
    <!-- 项目打包的默认名称 -->
    <finalName>${project.artifactId}-${project.version}</finalName>
    <!-- src/test/java,src/test/resources编译的存放路径 -->
    <testOutputDirectory>${project.build.directory}/test-classes</testOutputDirectory>
    <!-- 资源的存放路径 -->
    <sourceDirectory>${project.basedir}/src/main/java</sourceDirectory>
    <!-- 脚本的存放路径 -->
    <scriptSourceDirectory>${project.basedir}/src/main/scripts</scriptSourceDirectory>
    <!-- 测试的存放路径 -->
    <testSourceDirectory>${project.basedir}/src/test/java</testSourceDirectory>
    <!-- 配置资源的定义,包含src/main/resources-->
    <resources>
      <resource>
        <directory>${project.basedir}/src/main/resources</directory>
      </resource>
    </resources>
    <!-- 测试配置资源的定义,包含src/main/resources-->
    <testResources>
      <testResource>
        <directory>${project.basedir}/src/test/resources</directory>
      </testResource>
    </testResources>
    

     2.4.2 插件

    <pluginManagement>
      <!-- NOTE: These plugins will be removed from future versions of the super POM -->
      <!-- They are kept for the moment as they are very unlikely to conflict with lifecycle mappings (MNG-4453) -->
      <plugins>
        <plugin>
          <artifactId>maven-antrun-plugin</artifactId>
          <version>1.3</version>
        </plugin>
        <plugin>
          <artifactId>maven-assembly-plugin</artifactId>
          <version>2.2-beta-5</version>
        </plugin>
        <plugin>
          <artifactId>maven-dependency-plugin</artifactId>
          <version>2.8</version>
        </plugin>
        <plugin>
          <artifactId>maven-release-plugin</artifactId>
          <version>2.5.3</version>
        </plugin>
      </plugins>
    </pluginManagement>
    

      Super pom中定义了一些插件的版本,注释部分中看到这些配置项将来会被移除。

    2.5     报告

      调用site插件,可以生成项目的报告,在实际中,较少使用。它的源码如下:

     <reporting>
        <outputDirectory>${project.build.directory}/site</outputDirectory>
      </reporting>
    

      指定生成报告的路径。

    2.6     profile

      源码中可以看到,在将来会被移除。所以本部分内容略。

    <profiles>
        <!-- NOTE: The release profile will be removed from future versions of the super POM -->
    

    3、项目

      项目的知识点包含两个,项目自身,项目的关系。

    3.1   坐标

      一个机构可以开发多个项目,每个项目都有多个版本,每个版本都有不同的打包形式。

      项目的坐标就是由上述的几个核心信息构成的。

      groupId标签用于指定项目的机构信息

      artifactId标签用于指定项目的标识

      version标签用户指定项目的版本号,其中SNAPSHOT为快照版本,意思是正在开发中。release为发布版本,意思是已经开发完成,并且发布的稳定版本。

      packaging标签用于指定项目的打包形式,pom,war, jar。其中pom表示为抽象的maven项目,它通常是一个依赖的集合,或者是父项目。

    3.2  关系

      项目之间的关系有两种,继承关系和组合关系。

      继承关系主要是指父项目中包含多个子项目,要建立多层次的父子关系,可以使子项目同时承担父项目和子项目的角色。例如parent项目下包含childA,childB项目,childA项目又包含subchildA1, subchildA2等项目。

      它可以无限层级的嵌套,但是最好保持易用性。

      组合关系主要是指项目A依赖项目B,项目B又依赖项目C,是一种不闭环的链。若存在闭环时,会导致失败。例如A依赖B,B依赖C,C又依赖A。

      在管理依赖时,这两种方式都非常方便。

      继承时,子项目可以复用父项目的依赖,在引入时,可以省略版本信息。例如

    <dependency>
        <groupId>junit</groupId>
        <artifactId>junit</artifactId>
    </dependency>
    

      此处父项目中存在junit依赖,所以子项目可以省略版本号。可以把子项目公共的依赖放入父项目中。这样会非常方便。不过使用继承的大部分场景是模块化开发,即把项目拆分成多个小的项目,它们彼此之间相互依赖,但是可以同时并行开发。这符合当今主流的微服务架构。

      组合时,子项目可以添加项目依赖,或pom型依赖。项目依赖很常见,例如添加junit,logback,spring等依赖。它的缺点是需要自己独立的管理依赖的版本号,以及防止传递性依赖导致的冲突,传递性依赖指A依赖B,B依赖C,C依赖D等等,在Idea中可以使用maven helper分析传递性依赖。

      当有很多重复性的,公共的依赖时,可以把这些依赖整合为一个pom,例如把junit, logback, json, spring等等整合为com.example.common项目,它的packing类型为pom,之后引入com.example.common相当于引入很多这些重复性的,公共性的依赖。

    3.3      传递性依赖

      传递性依赖通常是组合关系,它很容易产生jar包的冲突,所以单独介绍。

      在运行项目,或者是编译之前,首先使用maven helper插件分析pom,看是否存在冲突。

      

       当Conflicts下面不存在任何内容时,表示无冲突。

      当存在冲突时,可以选择较为常见的,或者是较为稳定的版本,之后排除掉其他版本,鼠标右键,点击exclude即可。有了插件之后非常简单,若要使用命令行去分析,估计是非常困难。我曾经就有过这种痛苦的经历。

    3.4      作用域

      作用域有两个关键点,第一个是控制作用域的修饰符,或者是作用域的类型。第二个是作用域的适用范围。

      例如Java中类,属性的作用域,private, public, default, protected为作用域的类型。

      作用域的范围有单个对象,父子对象,同包,公开。

      Maven依赖的作用域也是同样的道理。它作用域的范围依据项目生命周期的三个阶段,编译,运行,打包。

      作用域的种类,或者是修饰符分为以下6种。

    1. compile:它是依赖的默认值,它会存在于任何的编译,存在于任何的运行,存在于最终打包的项目中,它的范围是最大的,类似于Java的public。
    2. test:它会存在于测试下的编译(src/test目录下),测试阶段的运行(junit运行),不会存在于最终打包的项目。它适用于测试的全阶段。
    3. runtime:它不存在于编译阶段,只存在于运行阶段,存在于最终打包的项目中,在编写代码时,引用这些依赖会报错。
    4. provided:它表示由相关的运行环境提供依赖,web项目的运行环境通常包含JDK和web server提供的jar。最常见的是servlet.api,它存在于编译,运行阶段,不会存在于最终打包的项目。
    5. system:它表示由系统提供,通常是指存放于文件系统中的依赖。当无法通过maven引入某个jar包,可以下载jar包,并提供jar包的路径,指定它的作用域为system。
    6. import:它表示引入的是pom类型的依赖,它通常是公共依赖的集合。

      后三种不能算是作用域,应该算是jar包的来源类型。类似于JVM加载class文件时,可以来源于项目,本地磁盘,网络等等。

    3.5      其他标签

      除与maven坐标有关,依赖有关的标签之外,还有一些其他的标签。下述介绍这些标签。

    1. classifier:表示JDK的版本,或者是编译的版本,同一个项目可以使用不同版本的JDK去编译,但是需要保证项目编译阶段,运行阶段高于依赖指定的JDK版本。
    2. systemPath:当scope为system时,指定jar包的物理地址
    3. optional:optional是指依赖关系的强制性还是按需性,类似于Java单例模式中的懒汉和恶汉。假设A依赖B时,在构建项目A时,是需要强制引入B,当optional为true时,只有引用B依赖时,才会去引入B。实现了B依赖的按需引入。
  • 相关阅读:
    【】Libevent源码解析
    sftp使用
    世界boss设计
    记一次薪酬谈判的教训 .
    一些常用的文件操作代码
    一位总经理的辞职信,以及回复
    JMeter安装、文档参考
    Charles——charles代理菜单proxy总结——external proxy 外部代理设置
    JDK安装
    Charles——charles常用功能——重定向
  • 原文地址:https://www.cnblogs.com/rain144576/p/14468792.html
Copyright © 2020-2023  润新知