modelVersion
  指定了当前Maven模型的版本号,描述这个POM文件是遵从哪个版本的项目描述符,对于Maven2和Maven3来说,它只能是4.0.0
项目的打包类型(packing):pom、jar、war
    项目中一般使用maven进行模块管理,每个模块下对应都有一个pom文件,pom文件中维护了各模块之间的依赖和继承关系。项目模块化可以将通用的部分抽离出来,方便重用;修改一部分代码不再是build整个项目,缩短了build时间;此外各模块都有自己的pom文件,结构更清晰。
使用maven进行模块划分管理,一般都会有一个父级项目,pom文件除了GAV(groupId, artifactId, version)是必须要配置的,另一个重要的属性就是packing打包类型,所有的父级项目的packing都为pom,packing默认是jar类型,如果不作配置,maven会将该项目打成jar包。作为父级项目,还有一个重要的属性,那就是modules,通过modules标签将项目的所有子项目引用进来,在build父级项目时,会根据子模块的相互依赖关系整理一个build顺序,然后依次build。
而对于各个子项目,需要在其对应的pom文件开头申明对父级项目的引用,通过GAV实现。对于子项目自己的GAV配置,GV如果不配置,则会从父级项目的配置继承过来。子模块可通过dependencies标签来添加自己的依赖,此外子类项目的packing值只能是war或者jar,前面已经说过,packing默认是jar类型。如果是需要部署的项目,则需要打包成war类型,如果只是内部调用或者是作服务使用,则推荐打包成jar类型。

optional是Maven依赖jar时的一个选项,表示该依赖是可选的,项目之间依赖不传递。不设置optional(默认)或者optional是false,表示传递依赖。

parent继承的情况

如果A的pom像下面这样配置:

<?xml version="1.0" encoding="UTF-8"?>
<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">
    <modelVersion>4.0.0</modelVersion>

    <groupId>A</groupId>
    <artifactId>A</artifactId>
    <version>1.0-SNAPSHOT</version>

    <dependencyManagement>
        <dependencies>
            <dependency>
                <groupId>joda-time</groupId>
                <artifactId>joda-time</artifactId>
                <version>2.9.9</version>
                <optional>true</optional>
            </dependency>
        </dependencies>
    </dependencyManagement>
</project>

B再去引用的话,还是可以正常引用joda-time包,optional选项在统一控制版本的情况下会失效。

<?xml version="1.0" encoding="UTF-8"?>
<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">
    <modelVersion>4.0.0</modelVersion>

    <groupId>B</groupId>
    <artifactId>B</artifactId>
    <version>1.0-SNAPSHOT</version>

    <parent>
        <groupId>A</groupId>
        <artifactId>A</artifactId>
        <version>1.0-SNAPSHOT</version>
    </parent>

    <dependencies>
        <dependency>
            <groupId>joda-time</groupId>
            <artifactId>joda-time</artifactId>
        </dependency>
    </dependencies>
</project>

在Maven项目中,恰当的使用optional配置,可以在很大程度上减少jar包的大小,提升编译和发布速度。

scope元素

scope元素主要用来控制依赖的使用范围,指定当前包的依赖范围和依赖的传递性,常见的可选值有:compile, provided, runtime, test:
compile(编译)
默认值。compile表示对应依赖会参与当前项目的编译、测试、运行等,是一个比较强的依赖。打包时通常会包含该依赖,部署时会打包到lib目录下。比如:spring-core这些核心的jar包。
test(测试)
scope为test表示依赖项目仅参与测试环节,在编译、运行、打包时不会使用。最常见的使用就是单元测试类,类似单元测试这样的依赖,如果不设置scope为test,很显然它们会被打包、发布,但其实真是环境中并无什么作用。

<dependency>
     <groupId>junit</groupId>
     <artifactId>junit</artifactId>
     <version>4.12</version>
     <scope>test</scope>
 </dependency>runntime(运行时)


runntime仅仅适用于运行和测试环节,在编译环境下不会被使用。比如编译时只需要JDBC API的jar,而只有运行时才需要JDBC驱动实现。

<dependency>
     <groupId>mysql</groupId>
     <artifactId>mysql-connector-java</artifactId>
     <version>8.0.20</version>
     <scope>runtime</scope>
 </dependency>
 provided(已提供)


provided适合在编译和测试的环境,和compile功能相似,但provide仅在编译和测试阶段生效,provide不会被打包,也不具有传递性。
比如:上面讲到的spring-boot-devtools、servlet-api等,前者是因为不需要在生产中热部署,后者是因为容器已经提供,不需要重复引入。

<dependency>
     <groupId>javax.servlet</groupId>
     <artifactId>javax.servlet-api</artifactId>
     <scope>provided</scope>
 </dependency>

scope依赖的传递性
上面scope的不同参数值,针对这些参数值,在多个项目中的依赖传递性如下:

maven mockmultipartfile依赖包 maven模块依赖_maven

其中B依赖A,C依赖B,传递性的关键是B依赖A时所设置的scope值,当B采用不同的值时对应的依赖关系如下:当B通过test或provided依赖A时,C不依赖A;当B通过runtime或compile依赖A时,C依赖A。

<type>pom</type> 用法说明
<!-- <type>pom</type>把spring-boot-dependencies引入为pom 文件 -->
 <!-- <scope>import</scope>解决单继承问题,类似parent标签,把spring-boot-dependencies引入到dependencyManagement --><dependencyManagement>
         <dependencies>
             <dependency>
                 <groupId>org.springframework.boot</groupId>
                 <artifactId>spring-boot-dependencies</artifactId>
                 <version>2.2.2.RELEASE</version>
                 <type>pom</type>
                 <scope>import</scope>
             </dependency>
         </dependencies>
 </dependencyManagement>