zoukankan      html  css  js  c++  java
  • 后端——工具——构建工具——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依赖的按需引入。
  • 相关阅读:
    数据结构-树与二叉树-思维导图
    The last packet successfully received from the server was 2,272 milliseconds ago. The last packet sent successfully to the server was 2,258 milliseconds ago.
    idea连接mysql报错Server returns invalid timezone. Go to 'Advanced' tab and set 'serverTimezone' property
    redis学习笔记
    AJAX校验注册用户名是否存在
    AJAX学习笔记
    JSON学习笔记
    JQuery基础知识学习笔记
    Filter、Listener学习笔记
    三层架构学习笔记
  • 原文地址:https://www.cnblogs.com/rain144576/p/14468792.html
Copyright © 2011-2022 走看看