【软件测试部署基础】maven的认识

  最近部门分享测试环境部署相关内容,在同事的分享下,学到了很多新的知识点,也是我们在测试环境部署的时候非常重要的一些基本的知识点,当你系统的去了解了一下,你会发现后端在maven相关的点上有个清晰的了解。

什么是Maven

在开发中经常需要依赖第三方的包,包与包之间存在依赖关系,版本间还有兼容性问题,有时还要将旧的包升级或降级,当项目复杂到一定程度时包管理变得非常重要。

在没有maven前的项目场景:

  • 如果使用了spring,去spring的官网下载jar包;如果使用hibernate,去hibernate的官网下载Jar包.....
  • 当某些jar包有依赖的时候,还要去下载对应的依赖jar包
  • 当jar包依赖有冲突时,需要一个一个的排查
  • 执行构建时,需要使用ant写出很多重复的任务代码
  • 当新人加入开发时,需要拷贝大量的jar包,然后重复进行构建
  • 当进行测试时,需要一个一个的运行,检查

使用maven后的项目场景:

  • 依赖的管理:仅仅通过jar包的几个属性,就能确定唯一的jar包,在指定的文件pom.xml中,只要(告诉Maven需要哪些Jar包)写入jar依赖属性,就会自动下载并管理jar包。
  • 项目的构建:内置很多的插件与生命周期,支持多种任务,比如校验、编译、测试、打包、部署、发布...
  • 项目的知识管理:管理项目相关的其他内容,比如包括项目描述、开发者列表、版本控制系统地址、许可证、缺陷管理系统地址等等

总的来说,Maven是一个项目管理和综合工具,可以帮助开发人员进行依赖管理、项目构建、项目知识管理等工作,极大的提升开发效率。

Maven作用

Maven 的本质是一个项目管理工具,将项目开发和管理过程抽象成一个项目对象模型(POM),开发人员只需做一些简单的配置,就可以批量完成项目的构建、报告和文档的生成工作。其主要功能如下:

  • Maven 统一集中管理所有的依赖包,不需要程序员再一一去寻找。

Maven 可以统一管理所有的依赖 jar,甚至是不同的版本。程序员也可以动态地将自己写好的模块打包成 jar 包让它管理。需要的时候,可以直接通过简单的描述文件告诉 Maven,它会自动帮助程序员找出来,集成到项目中。并且它提供了中央仓库,能帮我们自动下载构件。

  • 对应第三方组件用到的共同 jar,Maven 自动解决重复和冲突问题。

Maven 通过一个坐标系统准确地定位每一个构件(artifact),也就是通过一组坐标 Maven 能够找到任何一个 Java 类库(如 jar 文件)。Maven 给这个类库世界引入了经纬,让它们变得有秩序,于是我们可以借助它来有序地管理依赖,轻松地解决那些繁杂的依赖问题。

  • Maven 作为一个开放的架构,提供了公共接口,方便同第三方插件集成。

程序员可以将自己需要的插件,动态地集成到 Maven,从而扩展新的管理功能。

  • Maven 提供标准的构建生命周期、统一每个项目的构建过程。

在 Maven 之前,十个项目可能有十种构建方式。有了 Maven 之后,所有项目的构建命令都是标准化。

  • maven是跨平台的

无论是在 Windows 上,还是在 Linux 或者 Mac 上,都可以使用同样的命令进行项目的打包、构建等操作

  • 管理项目信息

Maven 还能管理原本分散在项目中各个角落的项目信息,包括项目描述、开发者列表、版本控制系统地址、许可证、缺陷管理系统地址等;除了直接的项目信息,通过 Maven 自动生成的站点,以及一些已有的插件,我们还能够轻松获得项目文档、测试报告、静态分析报告、源码版本日志报告等非常具有价值的项目信息。

maven安装

3.1 Linux安装演示

#1.进入maven官网http://maven.apache.org/download.cgi下载对应的压缩包。
#2.进入安装目录,并下载指定压缩包(当然可以本机下载后将文件共享至虚拟机
#的/usr/local(我们安装的目录选择在/usr/local)),执行命令:
cd /usr/local weget http://mirror.bit.edu.cn/apache/maven/maven-3/3.6.1/binaries/apache-maven-3.6.1-bin.tar.gz
#解压tar.gz文件,查看文件命令:
tar zxvf apache-maven-3.6.1-bin.tar.gz 
ll
#3.配置环境变量,vim进入etc/profile文件中填入如下内容
vim /etc/profile
#填入如下内容
export MAVEN_HOME=/var/local/apache-maven-3.6.1
export PATH=${PATH}:${MAVEN_HOME}/bin
#4.启动环境变量的配置
source /etc/profile
#5.验证maven是否安装成功
mvn -v
#6.安装完毕后,在桌面/home/xiong/Desktop/下创建一个test目录,并创建一个名为#project的文件夹,并创建pom.xml文件,内容如下:
<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>com.companyname.projectgroup</groupId>
<artifactId>project</artifactId>
<version>1.0</version>
<build>
    <plugins>
        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-antrun-plugin</artifactId>
            <version>1.1</version>
            <executions>
                <execution>
                    <id>id.pre-clean</id>
                    <phase>pre-clean</phase>
                    <goals>
                        <goal>run</goal>
                    </goals>
                    <configuration>
                        <tasks>
                            <echo>pre-clean phase</echo>
                        </tasks>
                    </configuration>
                </execution>
                <execution>
                    <id>id.clean</id>
                    <phase>clean</phase>
                    <goals>
                        <goal>run</goal>
                    </goals>
                    <configuration>
                        <tasks>
                            <echo>clean phase</echo>
                        </tasks>
                    </configuration>
                </execution>
                <execution>
                    <id>id.post-clean</id>
                    <phase>post-clean</phase>
                    <goals>
                        <goal>run</goal>
                    </goals>
                    <configuration>
                        <tasks>
                            <echo>post-clean phase</echo>
                        </tasks>
                    </configuration>
                </execution>
            </executions>
        </plugin>
    </plugins>
</build>
</project>
#执行命令,执行完毕后,就可以看到生成了一个target文件,文件里面包好的jar包文件。
mvn clean install

3.2 Windows安装演示

1.进入maven官网http://maven.apache.org/download.cgi下载对应的压缩包。
2.解压压缩包
3.配置环境变量
MAVEN_HOME:D:\apache-maven-3.6.3
Path:D:\apache-maven-3.6.3\bin或者%MAVEN_HOME%\bin
4.测试安装
CMD中输入mvn -v
5.测试使用
创建一个project文件夹,并加入pom.xml文件,内容同Linux
CMD中进入project目录,运行mvn clean install后,我们可以看到新增了一个target文件夹,文件夹中为打包好的project-1.0.jar包。

maven规定的目录结构

若要使用Maven,那么需要构建的项目的目录结构必须符合Maven的规范,其目录结构如下:

  

当然我们可以自己手动创建目录结构,但是这样过于繁琐,我们可以使用命令或者编辑器工具实现

4.1 使用命令的方式

  创建项目的命令需要使用Archetype 插件中的archetype-plugin,使用命令,会要求我们依次输入项目相关的信息包括 groupId(组 Id)、artifactId(构件 Id)、packageName(包名)、version(版本)

创建一个空的文件夹,CMD进入目录后,输入如下命令(需要注意的是在maven3.0.5以上版本舍弃了create,使用generate生成项目):

mvn archetype:generate 

然后会依次要求输入 groupId(组 Id)、artifactId(构件 Id)、packageName(包名)、version(版本)等。

创建完毕后,我们可以看到空文件夹中新增了一个与artifactId同名的文件夹

当然我们可以直接在命令中指定相应的信息:

创建普通的Java项目:

   mvn archetype:generate 
   -DgroupId=packageName 
   -DartifactId=projectName  

创建maven的web项目:

    mvn archetype:generate 
    -DgroupId=packageName    
    -DartifactId=webappName 
    -DarchetypeArtifactId=maven-archetype-webapp 

4.2 使用编辑器工具创建,如IDEA

(1) 在IDEA中配置maven

File=》Setting-Build=》Execution=》Deployment=》Build Tools=》Maven选择maven的安装路径,其他均默认后点击OK即完成maven的配置

(2) 创建新的maven项目File=》New=》Project填写GroupId、ArtifactId,创建完成,目录结构如下:

(3) 打包使用上面安装时的示例代码覆盖pom.xml后,点击右侧的maven,点击Lifecysle下的install进行项目的打包,如下所示:

Maven 构建生命周期

Maven 构建生命周期定义了一个项目构建和发布的过程,Maven 有以下三个标准的生命周期:

  • clean:项目清理的处理
  • default(或 build):项目部署的处理
  • site:项目站点文档创建的处理

5.1 Clean 生命周期

maven的clean生命周期主要是用于项目的清理,执行clean生命周期的命令,会自动清理构建目录下的输出文件(也就是target文件),当我们执行 mvn post-clean 命令时,Maven 调用 clean 生命周期,它包含以下阶段:

  • pre-clean:执行一些需要在clean之前完成的工作
  • clean:移除所有上一次构建生成的文件
  • post-clean:执行一些需要在clean之后立刻完成的工作

而我们使用mvn clean 中的 clean 就表示的上面的 clean阶段,在一个生命周期中,运行某个阶段的时候,它之前的所有阶段都会被运行,也就是说,如果执行 mvn clean 将运行以下两个生命周期阶段:

pre-clean, clean

如果我们运行 mvn post-clean ,则运行以下三个生命周期阶段:

pre-clean, clean, post-clean

5.2 Default (Build) 生命周期

maven的build生命周期也是maven默认的生命周期,是maven主要的生命周期,被用于构建应用,其包括下面的阶段:

而一个典型的 Maven 构建(build)生命周期主要是由以下几个阶段的序列组成的:当一个阶段通过 Maven 命令调用时,例如 mvn compile,只有该阶段之前以及包括该阶段在内的所有阶段会被执行。

Maven的Site生命周期一般用来创建新的报告文档、部署站点等,其主要包含如下阶段:

5.3 Site生命周期

  • pre-site:执行一些需要在生成站点文档之前完成的工作
  • site:生成项目的站点文档
  • post-site: 执行一些需要在生成站点文档之后完成的工作,并且为部署做准备
  • site-deploy:将生成的站点文档部署到特定的服务器上

这里经常用到的是site阶段和site-deploy阶段,用以生成和发布Maven站点,这Maven相当强大的功能,Manager比较喜欢,文档及统计数据自动生成。

5.4 构建阶段由插件目标构成

一个插件目标代表一个特定的任务(比构建阶段更为精细),这有助于项目的构建和管理。这些目标可能被绑定到多个阶段或者无绑定。不绑定到任何构建阶段的目标可以在构建生命周期之外通过直接调用执行。这些目标的执行顺序取决于调用目标和构建阶段的顺序。

例如,考虑下面的命令:

clean 和 pakage 是构建阶段,dependency:copy-dependencies 是目标

mvn clean dependency:copy-dependencies package

这里的 clean 阶段将会被首先执行,然后 dependency:copy-dependencies 目标会被执行,最终 package 阶段被执行。

5.5 基本常用命令

maven命令的调用基本就是在maven的生命周期前面添加一个mvn即可,使用maven命令我们可以只使用一个,也可以使用多个,如:

  • mvn install

这个命令在执行 install 阶段前,按顺序执行了 default 生命周期的阶段 (validate,compile,test,package,verify,install),我们只需要调用最后一个阶段,如这里是 install。

  • mvn clean deploy

这行命令也可以用于多模块的情况下,即包含多个子项目的项目,Maven 会在每一个子项目执行 clean 命令,然后再执行 deploy 命令。

Maven仓库

6.1 什么是maven仓库

构件:任何一个依赖、插件或者项目构件的输出,都可以成为构件。任何一个构件都有一组坐标唯一标识。

在此基础上,Maven就使用了仓库来统一存储所有Maven项目共享的构件。并且Maven项目将不再各自存储其依赖文件。它们只需要声明这些依赖的坐标,在需要的时候,Maven会自动根据坐标找到仓库中的构件,使用它们。

为了实现重用,项目构建完毕后生成的构件也可以安装或者部署到仓库中,供其他项目使用。

总的来说,Maven仓库用来存放Maven管理的所有构件。

6.2 仓库的布局

任何一个构件都有其唯一的坐标,根据这个坐标可以定义其在仓库中的唯一存储路径,这便是Maven的仓库布局方式(即构件的储存方式)。路径和坐标的大致对应关系为groupId/artifactId/version/artifactId-version.packaging,如

6.3 仓库的分类

对于Maven来说,仓库分为本地仓库和远程仓库。当Maven根据坐标寻找构件的时候,它首先会查看本地的仓库,如果本地仓库存在此构件,则直接使用;如果本地仓库不存在此构件,或者需要查看是否有更新的构件版本的时候,Maven就回去远程仓库查找,发现后下载到本地仓库再使用,如果本地和远程都不存在需要的构件,Maven就会报错。

仓库分类如下图:

 

6.3.1 本地仓库

默认情况下,不管是Windows还是Linux,每个用户在自己的用户目录下都有一个路径名为~/.m2/repository/的仓库目录(注意:要在安装maven,并第一次执行了maven命令后才会出现的)。可以通过配置修改仓库目录地址。可以编辑maven安装目录下的配置文件:如/usr/local/apache-maven-3.6.1/conf/settings.xml,设置localRepository元素的值为想要的仓库地址。

    例如:

  

    一个构件只有在本地仓库之后,才能由其他Maven项目使用,一般通过远程仓库下载,也可以将本地项目构件安装到本地Maven仓库中。使用命令mvn install 将本地项目构件存放到本地仓库。

6.3.2 远程仓库

    当用户输入第一条Maven命令之后,Maven才会创建本地仓库,然后根据配置和需要,从远程仓库下载构件至本地仓库。

6.3.2.1 中央仓库

由于原始的本地仓库是空的,Maven必须知道至少一个可用的远程仓库,才能在执行Maven命令的时候下载需要的构件。中央仓库是默认的远程仓库,Maven的安装目录自带了中央仓库的配置。在/usr/local/apache-maven-3.6.1/lib/maven-model-builder-3.6.1.jar的org/apache/maven/model/pom-4.0.0.xml。这个文件是所有Maven项目都会继承的超级POM。

使用id 为central对中央仓库进行唯一表示。name和 url 使用默认的仓库布局。snapshots元素子元素enabled的值为false,表示不会从该中央仓库下载快照版本的构件。

6.3.2.2 私服

    私服是特殊的远程仓库(可以简单的理解为局域网的中央仓库),它架设在局域网内的仓库服务,私服代理广域网上的远程仓库,供局域网内的Maven用户使用。当Maven需要下载构件的时候,它从私服请求,如果私服上不存在该构件,则从外部的远程仓库下载,缓存在私服之后,再为Maven的下载请求提供服务,此外,一些无法从外部仓库下载到的构件也可能从本地上传到私服上供大家使用。

6.3.2.2.1 私服有什么好处呢?

    ①节省自己的外网带宽

    ②加速Maven构件

    Maven的一些内部机制(例如快照更新检查)要求Maven在执行构件的时候不停的检查远程仓库数据,当项目配置了很多外部远程仓库的时候,构建的速度会大大降低。使用私服解决问题

    ③部署第三方构件

    当某个构件无法从任何一个外部远程仓库获得,怎么办?

    ④提高稳定性。增强控制

    Maven构件依赖远程仓库,Internet不稳定的时候,Maven构建也就不稳定。使用私服解决问题

    ⑤降低中央仓库的负荷

6.3.2.2.2 私服的配置

第一种方式:

因为我们的项目默认的情况下是从中央仓库来下载构建,因此我们可以把私服作为中央仓库的镜像。配置方式是在settings.xml中添加如下配置。

<mirror>
    <id>centralMirror</id>
    <name>mirror of central</name>
    <url>私服地址</url>
    <mirrorOf>central</mirrorOf>
</mirror>
#id标签:当前镜像的id,用为唯一标识当前的镜像。
#name标签:说明当前镜像的主要作用,便于我们阅读。
#url标签:私服的地址。
#mirrorOf标签:被镜像的远程仓库的id。因为我们现在配置的中央仓库的镜像。这里就要书写#中央仓库的id。

第二种方式:

在自己项目的pom.xml文件中配置远程仓库。我们项目的pom文件会继承maven安装路径下的一个超级pom,这也就是为什么当在本地找不到构件时,回去中央仓库寻找,是因为超级pom文件中配置了一个默认的远程中央仓库和插件仓库地址,因此我们可以将超级pom文件中的配置内容复制到我们项目的pom文件中,并将url地址改为私服地址即可。

<repositories>
<repository>
    <id>central</id>
    <name>Central Repository</name>
    <url>私服地址</url>
    <layout>default</layout>
    <snapshots>
        <enabled>false</enabled>
    </snapshots>
</repository>
</repositories>

<pluginRepositories>
<pluginRepository>
    <id>central</id>
    <name>Central Repository</name>
    <url>私服地址</url>
    <layout>default</layout>
    <snapshots>
        <enabled>false</enabled>
    </snapshots>
    <releases>
        <updatePolicy>never</updatePolicy>
    </releases>
</pluginRepository>
</pluginRepositories>

第三种方式:

方式二中的配置方式我们可以看出有个弊端,就是只有覆盖了超级pom中远程仓库的配置的项目才能使用到私服。假如本地的多个项目需要使用私服,那么就需要在每个项目的pom文件中进行一次配置,这样会进行许多重复的操作。解决的方法可以在settings.xml中配置远程仓库的地址为私服地址。

<profile>
<id>nexusProfile</id>
<repositories>
    <repository>
        <id>central</id>
        <name>Central Repository</name>
        <url>私服地址</url>
        <layout>default</layout>
        <snapshots>
            <enabled>false</enabled>
        </snapshots>
    </repository>
</repositories>
<pluginRepositories>
    <pluginRepository>
        <id>central</id>
        <name>Central Repository</name>
        <url>私服地址</url>
        <layout>default</layout>
        <snapshots>
            <enabled>false</enabled>
        </snapshots>
        <releases>
            <updatePolicy>never</updatePolicy>
        </releases>
    </pluginRepository>
</pluginRepositories>
</profile>

<!--远程仓库和插件的仓库的地址定义在profile标签中。此时需要为当前profile配置id的标签。然后需要启用当前配置的profile。启用的方式为:-->
<activeProfiles>
<!--激活上面的配置-->
<activeProfile>nexusProfile</activeProfile>
</activeProfiles>

6.3.2.3. 其他公共库

很多情况,默认的中央仓库无法满足项目需求,需要配置其他远程仓库。我们可以在pom文件中配置其他的一些仓库。

如下,我们配置一个jboss,地址为:http://repository.jboss.com/maven2的仓库

<project>
    <repositories>
    <repository>
        <id>jboss</id>
        <name>JBoss Repository</name>
        <url>http://repository.jboss.com/maven2</url>
        <releases>
            <enabled>true</enabled>
        </releases>
        <snapshots>
            <enabled>false</enabled>
            <updatedPolicy>daily</updatedPolicy>
            <checksumPolicy>ignore</checksumPolicy>
        </snapshots>
        <layout>default</layout>
    </repository>
    </repositories>
</project>

id:任何一个仓库的声明id必须是唯一的,尤其是注意Maven自带中央仓库的id是central,如果其他仓库声明也使用该id,就会覆盖中央仓库配置。
url:仓库地址
release:控制Maven对于发布版构件的下载。
snapshots:控制Maven对于快照版构件的下载。
enable:是否开启release或者snapshots的下载支持。
updatePolicy:用来配置Maven从远程仓库检查更新的频率,默认是daily,表示每天检查一次;never:从不检查更新;always:每次构建都检查更新;interval:X  每隔X分钟检查一次更新。
checksumPolicy:用来配置Maven检查检验和文件的策略。当构建被部署到Maven仓库中时,会同时部署对于应用的检验和文件,在下载构件的时候,Maven会验证校验和文件,如果失败?checksumPolicy默认值是warn,会执行构建时输出警告信息,其他可用——fail:遇到校验和错误就构件失败;ignore:完全忽略校验和错误。

POM基础配置

上面讲到了构件,而构件有一个唯一的标识,这个标识在Maven中就叫做坐标,Maven通过坐标在仓库中找到项目所需的Jar包。

groupId和artifactId构成了一个Jar包的坐标,如下一个pom.xml:

<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/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>
#通常是所需Jar包的项目名
<groupId>com.tiantian.mavenTest</groupId>
#通常是所需Jar包的模块名
<artifactId>projectA</artifactId>
#打包方式:默认是jar,还可以是war,pom,zip
<packaging>jar</packaging>
#第一个数字表示大版本号,第二个表示分支版本号,第三个表示小版本号
#snapshot 快照,alpha 内部测试,beta公测,Release稳定,GA正式发布
<version>1.0-SNAPSHOT</version>
#项目描述名
<name></name>
#项目地址
<url></url>
#项目描述
<description></description>
</project>

对于一个pom.xml来说有几个元素是必须定义的,一个是project根元素,然后就是它里面的modelVersion、groupId、artifactId和version。超级pom.xml中没有groupId、artifactId和version的定义,所以我们在建立自己的pom.xml的时候就需要定义这三个元素。

和java里面的继承类似,子pom.xml会完全继承父pom.xml中所有的元素,而且对于相同的元素,一般子pom.xml中的会覆盖父pom.xml中的元素,但是有几个特殊的元素它们会进行合并而不是覆盖。这些特殊的元素是:

  • dependencies
  • developers
  • contributors
  • plugin列表,包括plugin下面的reports
  • resources

POM配置之依赖

项目之间的依赖是通过pom.xml文件里面的dependencies元素下面的dependency元素进行的。一个dependency元素定义一个依赖关系。在dependency元素中我们主要通过依赖项目的groupId、artifactId和version来定义所依赖的项目。

先来看一个简单的项目依赖的示例吧,假设我现在有一个项目projectB,然后它里面有对junit的依赖,那么它的pom.xml就类似以下这个样子:

<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>com.tiantian.mavenTest</groupId>
<artifactId>projectB</artifactId>
<version>1.0-SNAPSHOT</version>
<packaging>jar</packaging>
<dependencies>
    <dependency>
        <groupId>junit</groupId>
        <artifactId>junit</artifactId>
        <version>3.8.1</version>
<packaging>jar</packaging>
        <scope>test</scope>
<exclusions>
<exclusion>
<groupId></groupId>
<artifactId></artifactId>
<version></version>
</exclusion>>
</exclusions>
        <optional>true</optional>
    </dependency>
</dependencies>
</project>
groupId, artifactId, version:描述了依赖的项目唯一标志。
packaging:对应于依赖项目的packaging类型,默认是jar。
scope:用于限制相应的依赖范围、传播范围。scope的主要取值范围如下:
n test:在测试范围有效,它在执行命令test的时候才执行,并且它不会传播给其他模块进行引入,比如 junit,dbunit 等测试框架
n compile(default 默认):这是它的默认值,这种类型很容易让人产生误解,以为只有在编译的时候才是需要的,其实这种类型表示所有的情况都是有用的,包括编译和运行时。而且这种类型的依赖性是可以传递的。
n runtime:在程序运行的时候依赖,在编译的时候不依赖。
n provided:这个跟compile很类似,但是它表示你期望这个依赖项目在运行时由JDK或者容器来提供。这种类型表示该依赖只有在测试和编译的情况下才有效,在运行时将由JDK或者容器提供。这种类型的依赖性是不可传递的。
n system:这种类型跟provided类似,唯一不同的就是这种类型的依赖我们要自己提供jar包,这需要与另一个元素systemPath来结合使用。systemPath将指向我们系统上的jar包的路径,而且必须是给定的绝对路径
systemPath:上面已经说过了这个元素是在scope的值为system的时候用于指定依赖的jar包在系统上的位置的,而且是绝对路径。该元素必须在依赖的 jar包的scope为system时才能使用,否则Maven将报错。
optional:设置依赖是否可选。当一个依赖是可选的时候,我们把optional元素的值设为true,否则就不设置optional元素,默认为false。
exclusions:排除依赖列表。

8.1 传递依赖与排除依赖

8.1.1 传递依赖

如果我们的项目引用了一个Jar包,而该Jar包又引用了其他Jar包,那么在默认情况下项目编译时,Maven会把直接引用和间接引用的Jar包都下载到本地。

8.1.2 排除依赖

考虑这样一种情况,我们的projectA依赖于projectB,然后projectB又依赖于projectC,但是在projectA里面我们不需要projectB依赖的projectC,那么这个时候我们就可以在依赖projectB的时候使用exclusions元素下面的exclusion排除projectC。这个时候我们需要在pom.xml中做如下配置(将需要排除的Jar包的坐标写在exclusion中):

<dependencies>
    <dependency>
        <exclusions>
            <exclusion>
                <groupId>cn.missbe.web.search</groupId>
                <artifactId>projectC</artifactId>
                <packaging>pom</packaging>
                <version>1.0-SNAPSHOT</version>
            </exclusion>
        </exclusions>
    </dependency>
</dependencies>

8.2 依赖冲突

若项目中多个Jar同时引用了相同的Jar时,会产生依赖冲突,但Maven采用了两种避免冲突的策略,因此在Maven中是不存在依赖冲突的。

8.2.1 短路优先

项目1——>A.jar——>B.jar——>X.jar
项目1——>C.jar——>X.jar

若本项目引用了A.jar,A.jar又引用了B.jar,B.jar又引用了X.jar,并且C.jar也引用了X.jar。

在此时,Maven只会引用路径最短的Jar,即使用第二种方式

8.2.2 声明优先

若引用路径长度相同时,在pom.xml中谁先被声明,就使用谁。

POM配置之继承(子项目需要引用父项目中的jar包)

9.1 什么是继承

在聚合多个项目时,如果这些被聚合的项目中需要引入相同的Jar,那么可以将这些Jar写入父pom中,各个子项目继承该pom即可。在子项目的pom中写父项目

9.2 如何实现继承

在父级的pom配置将需要继承的Jar包的坐标放入标签即可。

9.2.1 被继承项目与继承项目是父子目录关系

 现在假设我们有一个项目projectA,它的pom.xml定义如下:

<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/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.tiantian.mavenTest</groupId>
<artifactId>projectA</artifactId>
<packaging>jar</packaging>
<version>1.0-SNAPSHOT</version>
</project>

然后我们有另一个项目projectB,而且projectB是跟projectA的pom.xml文件处于同一个目录下,projectA、projectB的目录结构大体如下:

------projectA
    ------projectB
        -----pom.xml
    ------pom.xml

这时候如果projectB需要继承自projectA的话我们可以这样定义projectB的pom.xml文件。

<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/maven-v4_0_0.xsd">
    <parent>
        <groupId>com.tiantian.mavenTest</groupId>
        <artifactId>projectA</artifactId>
        <version>1.0-SNAPSHOT</version>
    </parent>
    <modelVersion>4.0.0</modelVersion>
    <groupId>com.tiantian.mavenTest</groupId>
    <artifactId>projectB</artifactId>
    <packaging>jar</packaging>
    <version>1.0-SNAPSHOT</version>
</project>

从上面projectB的pom.xml文件的定义我们可以知道,当需要继承指定的一个Maven项目时,我们需要在自己的pom.xml中定义一个parent元素,在这个元素中指明需要继承项目的groupId、artifactId和version。

9.2.2 被继承项目与继承项目的目录结构不是父子关系

当被继承项目与继承项目的目录结构不是父子关系的时候,我们再利用上面的配置是不能实现Maven项目的继承关系的,这个时候我们就需要在继承项目的pom.xml文件定义中的parent元素下再加上一个relativePath元素的定义,用以描述父项目的pom.xml文件相对于子项目的pom.xml文件的位置。

假设我们现在还是有上面两个项目,projectA和projectB,projectB还是继承自projectA,但是现在projectB不在projectA的子目录中,而是与projectA处于同一目录中。这个时候projectA和projectB的目录结构如下:

  ------projectA

    ------pom.xml

  ------projectB

    ------pom.xml

这个时候我们可以看出projectA的pom.xml相对于projectB的pom.xml的位置是“../projectA/pom.xml”,所以这个时候projectB的pom.xml的定义应该如下所示:

<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/maven-v4_0_0.xsd">
    <parent>
        <groupId>com.tiantian.mavenTest</groupId>
        <artifactId>projectA</artifactId>
        <version>1.0-SNAPSHOT</version>
        <relativePath>../projectA/pom.xml</relativePath>
    </parent>
    <modelVersion>4.0.0</modelVersion>
    <groupId>com.tiantian.mavenTest</groupId>
    <artifactId>projectB</artifactId>
    <packaging>jar</packaging>
    <version>1.0-SNAPSHOT</version>
</project>

10 POM配置之聚合(用于同时对多个项目做相同操作)

10.1 什么是聚合

对于聚合而言,当我们在被聚合的项目上使用Maven命令时,实际上这些命令都会在它的子模块项目上使用。这就是Maven中聚合的一个非常重要的作用。

假设这样一种场景,你同时需要打包或者编译projectA、projectB、projectC和projectD,按照正常的逻辑我们一个一个项目去使用mvn compile或mvn package进行编译和打包,对于使用Maven而言,你还是这样使用的话是非常麻烦的。因为Maven给我们提供了聚合的功能。我们只需要再定义一个超级项目,然后在超级项目的pom.xml中定义这个几个项目都是聚合到这个超级项目的。之后我们只需要对这个超级项目进行mvn compile,它就会把那些子模块项目都进行编译。

也就是对超级项目操作时,就对超级项目中的所有子项目进行了相同的操作;在父级的pom中写子项目

10.2 如何实现聚合

两个步骤:

  • 修改被聚合父项目的pom.xml中的packaging元素的值为pom
  • 在被聚合父项目的pom.xml中的modules元素下指定它的子模块项目

10.2.1 被聚合项目和子模块项目在目录结构上是父子关系

  还拿上面定义的projectA和projectB来举例子,现在假设我们需要把projectB聚合到projectA中。projectA和projectB的目录结构如下所示:

  ------projectA

     ------projectB

       -----pom.xml

     ------pom.xml

  这个时候projectA的pom.xml应该这样定义:

<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>com.tiantian.mavenTest</groupId>
    <artifactId>projectA</artifactId>
    <version>1.0-SNAPSHOT</version>
    <packaging>pom</packaging>
    <modules>
        <module>projectB</module>
    </modules>
</project>

由上面的定义我们可以看到被聚合的项目的packaging类型应该为pom,而且一个项目可以有多个子模块项目。

对于聚合这种情况,我们使用子模块项目的artifactId来作为module的值,表示子模块项目相对于被聚合项目的地址,在上面的示例中就表示子模块projectB是处在被聚合项目的子目录下,即与被聚合项目的pom.xml处于同一目录。这里使用的module值是子模块projectB对应的目录名projectB,而不是子模块对应的artifactId。这个时候当我们对projectA进行mvn package命令时,实际上Maven也会对projectB进行打包。

10.2.2 被聚合项目与子模块项目在目录结构上不是父子关系

  那么当被聚合项目与子模块项目在目录结构上不是父子关系的时候,具体做法是在module元素中指定以相对路径的方式指定子模块。我们来看下面一个例子。

  继续使用上面的projectA和projectB,还是需要把projectB聚合到projectA,但是projectA和projectB的目录结构不再是父子关系,而是如下所示的这种关系:

  ------projectA

    ------pom.xml

  ------projectB

    ------pom.xml

  这个时候projectA的pom.xml文件就应该这样定义:

<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>com.tiantian.mavenTest</groupId>
    <artifactId>projectA</artifactId>
    <version>1.0-SNAPSHOT</version>
    <packaging>pom</packaging>
    <modules>
        <module>../projectB</module>
    </modules>
</project>

注意看module的值是“../projectB”,我们知道“..”是代表当前目录的上层目录,所以它表示子模块projectB是被聚合项目projectA的pom.xml文件所在目录(即projectA)的上层目录下面的子目录,即与projectA处于同一目录层次。

10.2.3 聚合与继承同时进行

假设有这样一种情况,有两个项目,projectA和projectB,现在我们需要projectB继承projectA,同时需要把projectB聚合到projectA。然后projectA和projectB的目录结构如下:

       ------projectA

              ------pom.xml

       ------projectB

              ------pom.xml

那么这个时候按照上面说的那样,projectA的pom.xml中需要定义它的packaging为pom,需要定义它的modules,所以projectA的pom.xml应该这样定义:

<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>com.tiantian.mavenTest</groupId>
    <artifactId>projectA</artifactId>
    <version>1.0-SNAPSHOT</version>
    <packaging>pom</packaging>
    <modules>
        <module>../projectB</module>
    </modules>
</project>

而projectB是继承自projectA的,所以我们需要在projectB的pom.xml文件中新增一个parent元素,用以定义它继承的项目信息。所以projectB的pom.xml文件的内容应该这样定义:

<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>
    <parent>
        <groupId>com.tiantian.mavenTest</groupId>
        <artifactId>projectA</artifactId>
        <version>1.0-SNAPSHOT</version>
        <relativePath>../projectA/pom.xml</relativePath>
    </parent>
    <groupId>com.tiantian.mavenTest</groupId>
    <artifactId>projectB</artifactId>
    <version>1.0-SNAPSHOT</version>
    <packaging>jar</packaging>
</project>

11 其他问题

  1.使用mvn archetype:create -DgroupId=com.oreilly -DartifactId=my-app来创建一个普通的Java项目时,无法创建。 

上网得知此问题是因为:

create is deprecated in maven 3.0.5 and beyond,在maven3.0.5以上版本舍弃了create,使用generate生成项目

所以解决方案就是,将create更换为generate即可

  2.mvn clean package -P prod中的-P是什么意思?以及mvn -D表示什么?

#mvn clean package -P prod中的-P是什么意思?以及mvn -D表示什么?
#D代表(Properties属性) #假如POM文件的部分内容如下: <properties> <attr>defaultattr</attr> </properties> #那么执行如下的命令pom.xml内attr的实际值将被替换成newattr mvn -Dattr=newattr clean package #命令方式: mvn -DpropertyName=propertyValue clean package #如果propertyName不存在pom.xml,它将被设置。 #如果propertyName已经存在pom.xml,其值将被作为参数传递的值覆盖-D。 #要发送多个变量,请使用多个空格分隔符加-D: mvn -DpropA=valueA -DpropB=valueB -DpropC=valueC clean package #P代表(Profiles配置文件) #在<profiles>指定的<id>中,可以通过-P进行传递或者赋值。 #假如POM文件的部分内容如下: <profiles> <profile> <id>prod</id> ... </profile> <profile> <id>test</id> ... </profile> #打包时执行如下命令,将触发test环境的profile配置。比如:-Pproduction 使用setting.xml中production的配置. mvn clean package -P test

 

[root@ecs-b936 conf]$ cat settings.xml 
<?xml version="1.0" encoding="UTF-8"?>

<!--
Licensed to the Apache Software Foundation (ASF) under one
or more contributor license agreements.  See the NOTICE file
distributed with this work for additional information
regarding copyright ownership.  The ASF licenses this file
to you under the Apache License, Version 2.0 (the
"License"); you may not use this file except in compliance
with the License.  You may obtain a copy of the License at

    http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing,
software distributed under the License is distributed on an
"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
KIND, either express or implied.  See the License for the
specific language governing permissions and limitations
under the License.
-->

<!--
 | This is the configuration file for Maven. It can be specified at two levels:
 |
 |  1. User Level. This settings.xml file provides configuration for a single user, 
 |                 and is normally provided in ${user.home}/.m2/settings.xml.
 |
 |                 NOTE: This location can be overridden with the CLI option:
 |
 |                 -s /path/to/user/settings.xml
 |
 |  2. Global Level. This settings.xml file provides configuration for all Maven
 |                 users on a machine (assuming they're all using the same Maven
 |                 installation). It's normally provided in 
 |                 ${maven.home}/conf/settings.xml.
 |
 |                 NOTE: This location can be overridden with the CLI option:
 |
 |                 -gs /path/to/global/settings.xml
 |
 | The sections in this sample file are intended to give you a running start at
 | getting the most out of your Maven installation. Where appropriate, the default
 | values (values used when the setting is not specified) are provided.
 |
 |-->
<settings xmlns="http://maven.apache.org/SETTINGS/1.0.0" 
          xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
          xsi:schemaLocation="http://maven.apache.org/SETTINGS/1.0.0 http://maven.apache.org/xsd/settings-1.0.0.xsd">
  <!-- localRepository
   | The path to the local repository maven will use to store artifacts.
   |
   | Default: ~/.m2/repository
  -->
        <localRepository>/opt/haishu/maven3/repository_02</localRepository>

  <!-- interactiveMode
   | This will determine whether maven prompts you when it needs input. If set to false,
   | maven will use a sensible default value, perhaps based on some other setting, for
   | the parameter in question.
   |
   | Default: true
  <interactiveMode>true</interactiveMode>
  -->

  <!-- offline
   | Determines whether maven should attempt to connect to the network when executing a build.
   | This will have an effect on artifact downloads, artifact deployment, and others.
   |
   | Default: false
  <offline>false</offline>
  -->

  <!-- pluginGroups
   | This is a list of additional group identifiers that will be searched when resolving plugins by their prefix, i.e.
   | when invoking a command line like "mvn prefix:goal". Maven will automatically add the group identifiers
   | "org.apache.maven.plugins" and "org.codehaus.mojo" if these are not already contained in the list.
   |-->
  <pluginGroups>
    <!-- pluginGroup
     | Specifies a further group identifier to use for plugin lookup.
    <pluginGroup>com.your.plugins</pluginGroup>
    -->
  </pluginGroups>

  <!-- proxies
   | This is a list of proxies which can be used on this machine to connect to the network.
   | Unless otherwise specified (by system property or command-line switch), the first proxy
   | specification in this list marked as active will be used.
   |-->
  <proxies>
    <!-- proxy
     | Specification for one proxy, to be used in connecting to the network.
     |
    <proxy>
      <id>optional</id>
      <active>true</active>
      <protocol>http</protocol>
      <username>proxyuser</username>
      <password>proxypass</password>
      <host>proxy.host.net</host>
      <port>80</port>
      <nonProxyHosts>local.net|some.host.com</nonProxyHosts>
    </proxy>
    -->
  </proxies>

  <!-- servers
   | This is a list of authentication profiles, keyed by the server-id used within the system.
   | Authentication profiles can be used whenever maven must make a connection to a remote server.
   |-->
  <servers>
    <!-- server
     | Specifies the authentication information to use when connecting to a particular server, identified by
     | a unique name within the system (referred to by the 'id' attribute below).
     | 
     | NOTE: You should either specify username/password OR privateKey/passphrase, since these pairings are 
     |       used together.
     |
    <server>
      <id>deploymentRepo</id>
      <username>repouser</username>
      <password>repopwd</password>
    </server>
    -->
    
    <!-- Another sample, using keys to authenticate.
    <server>
      <id>siteServer</id>
      <privateKey>/path/to/private/key</privateKey>
      <passphrase>optional; leave empty if not used.</passphrase>
    </server>
    -->
  </servers>

  <!-- mirrors
   | This is a list of mirrors to be used in downloading artifacts from remote repositories.
   | 
   | It works like this: a POM may declare a repository to use in resolving certain artifacts.
   | However, this repository may have problems with heavy traffic at times, so people have mirrored
   | it to several places.
   |
   | That repository definition will have a unique id, so we can create a mirror reference for that
   | repository, to be used as an alternate download site. The mirror site will be the preferred 
   | server for that repository.
   |-->
  <mirrors>
    <!-- mirror
     | Specifies a repository mirror site to use instead of a given repository. The repository that
     | this mirror serves has an ID that matches the mirrorOf element of this mirror. IDs are used
     | for inheritance and direct lookup purposes, and must be unique across the set of mirrors.
     |
    <mirror>
      <id>mirrorId</id>
      <mirrorOf>repositoryId</mirrorOf>
      <name>Human Readable Name for this Mirror.</name>
      <url>http://my.repository.com/repo/path</url>
    </mirror>
     -->
  </mirrors>
  
  <!-- profiles
   | This is a list of profiles which can be activated in a variety of ways, and which can modify
   | the build process. Profiles provided in the settings.xml are intended to provide local machine-
   | specific paths and repository locations which allow the build to work in the local environment.
   |
   | For example, if you have an integration testing plugin - like cactus - that needs to know where
   | your Tomcat instance is installed, you can provide a variable here such that the variable is 
   | dereferenced during the build process to configure the cactus plugin.
   |
   | As noted above, profiles can be activated in a variety of ways. One way - the activeProfiles
   | section of this document (settings.xml) - will be discussed later. Another way essentially
   | relies on the detection of a system property, either matching a particular value for the property,
   | or merely testing its existence. Profiles can also be activated by JDK version prefix, where a 
   | value of '1.4' might activate a profile when the build is executed on a JDK version of '1.4.2_07'.
   | Finally, the list of active profiles can be specified directly from the command line.
   |
   | NOTE: For profiles defined in the settings.xml, you are restricted to specifying only artifact
   |       repositories, plugin repositories, and free-form properties to be used as configuration
   |       variables for plugins in the POM.
   |
   |-->
  <profiles>
    <!-- profile
     | Specifies a set of introductions to the build process, to be activated using one or more of the
     | mechanisms described above. For inheritance purposes, and to activate profiles via <activatedProfiles/>
     | or the command line, profiles have to have an ID that is unique.
     |
     | An encouraged best practice for profile identification is to use a consistent naming convention
     | for profiles, such as 'env-dev', 'env-test', 'env-production', 'user-jdcasey', 'user-brett', etc.
     | This will make it more intuitive to understand what the set of introduced profiles is attempting
     | to accomplish, particularly when you only have a list of profile id's for debug.
     |
     | This profile example uses the JDK version to trigger activation, and provides a JDK-specific repo.
    <profile>
      <id>jdk-1.4</id>

      <activation>
        <jdk>1.4</jdk>
      </activation>

      <repositories>
        <repository>
          <id>jdk14</id>
          <name>Repository for JDK 1.4 builds</name>
          <url>http://www.myhost.com/maven/jdk14</url>
          <layout>default</layout>
          <snapshotPolicy>always</snapshotPolicy>
        </repository>
      </repositories>
    </profile>
    -->

    <!--
     | Here is another profile, activated by the system property 'target-env' with a value of 'dev',
     | which provides a specific path to the Tomcat instance. To use this, your plugin configuration
     | might hypothetically look like:
     |
     | ...
     | <plugin>
     |   <groupId>org.myco.myplugins</groupId>
     |   <artifactId>myplugin</artifactId>
     |   
     |   <configuration>
     |     <tomcatLocation>${tomcatPath}</tomcatLocation>
     |   </configuration>
     | </plugin>
     | ...
     |
     | NOTE: If you just wanted to inject this configuration whenever someone set 'target-env' to
     |       anything, you could just leave off the <value/> inside the activation-property.
     |
    <profile>
      <id>env-dev</id>

      <activation>
        <property>
          <name>target-env</name>
          <value>dev</value>
        </property>
      </activation>

      <properties>
        <tomcatPath>/path/to/tomcat/instance</tomcatPath>
      </properties>
    </profile>
    -->
  </profiles>

  <!-- activeProfiles
   | List of profiles that are active for all builds.
   |
  <activeProfiles>
    <activeProfile>alwaysActiveProfile</activeProfile>
    <activeProfile>anotherAlwaysActiveProfile</activeProfile>
  </activeProfiles>
  -->
</settings>

 

 

 

12 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.0http://maven.apache.org/maven-v4_0_0.xsd">
  <!--父项目的坐标。如果项目中没有规定某个元素的值,那么父项目中的对应值即为项目的默认值。 坐标包括group ID,artifact ID和 version。-->
  <parent>
    <!--被继承的父项目的构件标识符-->
    <artifactId/>
    <!--被继承的父项目的全球唯一标识符-->
    <groupId/>
    <!--被继承的父项目的版本-->
    <version/>
  </parent>
  <!--声明项目描述符遵循哪一个POM模型版本。模型本身的版本很少改变,虽然如此,但它仍然是必不可少的,这是为了当Maven引入了新的特性或者其他模型变更的时候,确保稳定性。-->
  <modelVersion>4.0.0</modelVersion>
  <!--项目的全球唯一标识符,通常使用全限定的包名区分该项目和其他项目。并且构建时生成的路径也是由此生成, 如com.mycompany.app生成的相对路径为:/com/mycompany/app-->
  <groupId>cn.missbe.web</groupId>
  <!-- 构件的标识符,它和group ID一起唯一标识一个构件。换句话说,你不能有两个不同的项目拥有同样的artifact ID和groupID;在某个特定的group ID下,artifact ID也必须是唯一的。构件是项目产生的或使用的一个东西,
  Maven为项目产生的构件包括:JARs,源码,二进制发布和WARs等。-->
  <artifactId>search-resources</artifactId>
  <!--项目产生的构件类型,例如jar、war、ear、pom。插件可以创建他们自己的构件类型,所以前面列的不是全部构件类型-->
  <packaging>war</packaging>
  <!--项目当前版本,格式为:主版本.次版本.增量版本-限定版本号-->
  <version>1.0-SNAPSHOT</version>
  <!--项目的名称, Maven产生的文档用-->
  <name>search-resources</name>
  <!--项目主页的URL, Maven产生的文档用-->
  <url>http://www.missbe.cn</url>
  <!-- 项目的详细描述, Maven 产生的文档用。  当这个元素能够用HTML格式描述时(例如,CDATA中的文本会被解析器忽略,就可以包含HTML标 签), 不鼓励使用纯文本描述。如果你需要修改产生的web站点的索引页面,
  你应该修改你自己的索引页文件,而不是调整这里的文档。-->
  <description>A maven project to study maven.</description>
  <!--描述了这个项目构建环境中的前提条件。-->
  <prerequisites>
  <!--构建该项目或使用该插件所需要的Maven的最低版本-->
  <maven/>
  </prerequisites>

  <!--构建项目需要的信息-->
  <build>
    <!--该元素设置了项目源码目录,当构建项目的时候,构建系统会编译目录里的源码。该路径是相对于pom.xml的相对路径。-->
    <sourceDirectory/>
    <!--该元素设置了项目脚本源码目录,该目录和源码目录不同:绝大多数情况下,该目录下的内容 会被拷贝到输出目录(因为脚本是被解释的,而不是被编译的)。-->
    <scriptSourceDirectory/>
    <!--该元素设置了项目单元测试使用的源码目录,当测试项目的时候,构建系统会编译目录里的源码。该路径是相对于pom.xml的相对路径。-->
    <testSourceDirectory/>
    <!--被编译过的应用程序class文件存放的目录。-->
    <outputDirectory/>
    <!--被编译过的测试class文件存放的目录。-->
    <testOutputDirectory/>
    <!--使用来自该项目的一系列构建扩展-->
    <extensions>
      <!--描述使用到的构建扩展。-->
      <extension>
          <!--构建扩展的groupId-->
          <groupId/>
          <!--构建扩展的artifactId-->
          <artifactId/>
          <!--构建扩展的版本-->
          <version/>
      </extension>
    </extensions>
  <!--这个元素描述了项目相关的所有资源路径列表,例如和项目相关的属性文件,这些资源被包含在最终的打包文件里。-->
  <resources>
    <!--这个元素描述了项目相关或测试相关的所有资源路径-->
    <resource>
      <!-- 描述了资源的目标路径。该路径相对target/classes目录(例如${project.build.outputDirectory})。举个例 子,如果你想资源在特定的包里(org.apache.maven.messages),你就必须该元素设置为org/apache/maven /messages。然而,如果你只是想把资源放到源码目录结构里,就不需要该配置。-->
      <targetPath/>
      <!--是否使用参数值代替参数名。参数值取自properties元素或者文件里配置的属性,文件在filters元素里列出。-->
      <filtering/>
      <!--描述存放资源的目录,该路径相对POM路径-->
      <directory/>
      <!--包含的模式列表,例如**/*.xml.-->
      <includes/>
      <!--排除的模式列表,例如**/*.xml-->
      <excludes/>
    </resource>
  </resources>
  <!--这个元素描述了单元测试相关的所有资源路径,例如和单元测试相关的属性文件。-->
  <testResources>
    <!--这个元素描述了测试相关的所有资源路径,参见build/resources/resource元素的说明-->
    <testResource>
      <targetPath/><filtering/><directory/><includes/><excludes/>
    </testResource>
  </testResources>
  <!--构建产生的所有文件存放的目录-->
  <directory/>
  <!--产生的构件的文件名,默认值是${artifactId}-${version}。-->
  <finalName/>
  <!--当filtering开关打开时,使用到的过滤器属性文件列表-->
  <filters/>
  <!--子项目可以引用的默认插件信息。该插件配置项直到被引用时才会被解析或绑定到生命周期。给定插件的任何本地配置都会覆盖这里的配置-->
  <pluginManagement>
    <!--使用的插件列表 。-->
    <plugins>
      <!--plugin元素包含描述插件所需要的信息。-->
      <plugin>
        <!--插件在仓库里的group ID-->
        <groupId/>
        <!--插件在仓库里的artifact ID-->
        <artifactId/>
        <!--被使用的插件的版本(或版本范围)-->
        <version/>
        <!--是否从该插件下载Maven扩展(例如打包和类型处理器),由于性能原因,只有在真需要下载时,该元素才被设置成enabled。-->
        <extensions/>
        <!--在构建生命周期中执行一组目标的配置。每个目标可能有不同的配置。-->
        <executions>
          <!--execution元素包含了插件执行需要的信息-->
          <execution>
            <!--执行目标的标识符,用于标识构建过程中的目标,或者匹配继承过程中需要合并的执行目标-->
            <id/>
            <!--绑定了目标的构建生命周期阶段,如果省略,目标会被绑定到源数据里配置的默认阶段-->
            <phase/>
            <!--配置的执行目标-->
            <goals/>
            <!--配置是否被传播到子POM-->
            <inherited/>
            <!--作为DOM对象的配置-->
            <configuration/>
          </execution>
        </executions>
          <!--项目引入插件所需要的额外依赖-->
          <dependencies>
            <!--参见dependencies/dependency元素-->
            <dependency>
              ......
            </dependency>
          </dependencies>
          <!--任何配置是否被传播到子项目-->
          <inherited/>
          <!--作为DOM对象的配置-->
          <configuration/>
        </plugin>
      </plugins>
    </pluginManagement>
    <!--使用的插件列表-->
    <plugins>
      <!--参见build/pluginManagement/plugins/plugin元素-->
      <plugin>
        <groupId/><artifactId/><version/><extensions/>
        <executions>
          <execution>
            <id/><phase/><goals/><inherited/><configuration/>
          </execution>
        </executions>
        <dependencies>
          <!--参见dependencies/dependency元素-->
          <dependency>
            ......
          </dependency>
        </dependencies>
        <goals/><inherited/><configuration/>
      </plugin>
    </plugins>
  </build>
  <!--模块(有时称作子项目) 被构建成项目的一部分。
  列出的每个模块元素是指向该模块的目录的相对路径-->
  <modules/>
  <!--发现依赖和扩展的远程仓库列表。-->
  <repositories>
    <!--包含需要连接到远程仓库的信息-->
    <repository>
      <!--如何处理远程仓库里发布版本的下载-->
      <releases>
        <!--true或者false表示该仓库是否为下载某种类型构件(发布版,快照版)开启。 -->
        <enabled/>
        <!--该元素指定更新发生的频率。Maven会比较本地POM和远程POM的时间戳。这里的选项是:always(一直),daily(默认,每日),interval:X(这里X是以分钟为单位的时间间隔),或者never(从不)。-->
        <updatePolicy/>
        <!--当Maven验证构件校验文件失败时该怎么做:ignore(忽略),fail(失败),或者warn(警告)。-->
        <checksumPolicy/>
      </releases>
      <!-- 如何处理远程仓库里快照版本的下载。有了releases和snapshots这两组配置,POM就可以在每个单独的仓库中,为每种类型的构件采取不同的 策略。例如,可能有人会决定只为开发目的开启对快照版本下载的支持。参见repositories/repository/releases元素 -->
      <snapshots>
        <enabled/><updatePolicy/><checksumPolicy/>
      </snapshots>
      <!--远程仓库唯一标识符。可以用来匹配在settings.xml文件里配置的远程仓库-->
      <id>banseon-repository-proxy</id>
      <!--远程仓库名称-->
      <name>banseon-repository-proxy</name>
      <!--远程仓库URL,按protocol://hostname/path形式-->
      <url>http://192.168.1.169:9999/repository/</url>
      <!-- 用于定位和排序构件的仓库布局类型-可以是default(默认)或者legacy(遗留)。Maven 2为其仓库提供了一个默认的布局;然 而,Maven 1.x有一种不同的布局。我们可以使用该元素指定布局是default(默认)还是legacy(遗留)。-->
      <layout>default</layout>
    </repository>
  </repositories>
  <!--发现插件的远程仓库列表,这些插件用于构建和报表-->
  <pluginRepositories>
    <!--包含需要连接到远程插件仓库的信息.参见repositories/repository元素-->
    <pluginRepository>
      ......
    </pluginRepository>
  </pluginRepositories>

  <!--该元素描述了项目相关的所有依赖。 这些依赖组成了项目构建过程中的一个个环节。它们自动从项目定义的仓库中下载。要获取更多信息,请看项目依赖机制。-->
  <dependencies>
    <dependency>
      <!--依赖的group ID-->
      <groupId>org.apache.maven</groupId>
      <!--依赖的artifact ID-->
      <artifactId>maven-artifact</artifactId>
      <!--依赖的版本号。 在Maven 2里, 也可以配置成版本号的范围。-->
      <version>3.8.1</version>
      <!-- 依赖类型,默认类型是jar。它通常表示依赖的文件的扩展名,但也有例外。一个类型可以被映射成另外一个扩展名或分类器。类型经常和使用的打包方式对应,尽管这也有例外。一些类型的例子:jar,war,ejb-client和test-jar。如果设置extensions为 true,就可以在 plugin里定义新的类型。所以前面的类型的例子不完整。-->
      <type>jar</type>
      <!-- 依赖的分类器。分类器可以区分属于同一个POM,但不同构建方式的构件。分类器名被附加到文件名的版本号后面。例如,如果你想要构建两个单独的构件成 JAR,一个使用Java 1.4编译器,另一个使用Java 6编译器,你就可以使用分类器来生成两个单独的JAR构件。-->
      <classifier></classifier>
      <!--依赖范围。在项目发布过程中,帮助决定哪些构件被包括进来。欲知详情请参考依赖机制。
          - compile :默认范围,用于编译
          - provided:类似于编译,但支持你期待jdk或者容器提供,类似于classpath
          - runtime: 在执行时需要使用
          - test:    用于test任务时使用
          - system: 需要外在提供相应的元素。通过systemPath来取得
          - systemPath: 仅用于范围为system。提供相应的路径
          - optional:   当项目自身被依赖时,标注依赖是否传递。用于连续依赖时使用-->
      <scope>test</scope>
      <!--仅供system范围使用。注意,不鼓励使用这个元素,并且在新的版本中该元素可能被覆盖掉。该元素为依赖规定了文件系统上的路径。需要绝对路径而不是相对路径。推荐使用属性匹配绝对路径,例如${java.home}。-->
      <systemPath></systemPath>
      <!--当计算传递依赖时, 从依赖构件列表里,列出被排除的依赖构件集。即告诉maven你只依赖指定的项目,不依赖项目的依赖。此元素主要用于解决版本冲突问题-->
      <exclusions>
        <exclusion>
          <artifactId>spring-core</artifactId>
          <groupId>org.springframework</groupId>
        </exclusion>
      </exclusions>
      <!--可选依赖,如果你在项目B中把C依赖声明为可选,你就需要在依赖于B的项目(例如项目A)中显式的引用对C的依赖。可选依赖阻断依赖的传递性。-->
      <optional>true</optional>
    </dependency>
  </dependencies>


  <!-- 继承自该项目的所有子项目的默认依赖信息。这部分的依赖信息不会被立即解析,而是当子项目声明一个依赖(必须描述group ID和 artifact ID信息),如果group ID和artifact ID以外的一些信息没有描述,则通过group ID和artifact ID 匹配到这里的依赖,并使用这里的依赖信息。-->
  <dependencyManagement>
    <dependencies>
      <!--参见dependencies/dependency元素-->
      <dependency>
        ......
      </dependency>
    </dependencies>
  </dependencyManagement>
  <!--项目分发信息,在执行mvn deploy后表示要发布的位置。有了这些信息就可以把网站部署到远程服务器或者把构件部署到远程仓库。-->
  <distributionManagement>
    <!--部署项目产生的构件到远程仓库需要的信息-->
    <repository>
      <!--是分配给快照一个唯一的版本号(由时间戳和构建流水号)?还是每次都使用相同的版本号?参见repositories/repository元素-->
      <uniqueVersion/>
      <id>banseon-maven2</id>
      <name>banseon maven2</name>
      <url>file://${basedir}/target/deploy</url>
      <layout/>
    </repository>
    <!--构件的快照部署到哪里?如果没有配置该元素,默认部署到repository元素配置的仓库,参见distributionManagement/repository元素-->
    <snapshotRepository>
      <uniqueVersion/>
      <id>banseon-maven2</id>
      <name>Banseon-maven2 Snapshot Repository</name>
      <url>scp://svn.baidu.com/banseon:/usr/local/maven-snapshot</url>
      <layout/>
    </snapshotRepository>
    <!--部署项目的网站需要的信息-->
    <site>
      <!--部署位置的唯一标识符,用来匹配站点和settings.xml文件里的配置-->
      <id>banseon-site</id>
      <!--部署位置的名称-->
      <name>business api website</name>
      <!--部署位置的URL,按protocol://hostname/path形式-->
      <url>
        scp://svn.baidu.com/banseon:/var/www/localhost/banseon-web
      </url>
    </site>
    <!--项目下载页面的URL。如果没有该元素,用户应该参考主页。使用该元素的原因是:帮助定位那些不在仓库里的构件(由于license限制)。-->
    <downloadUrl/>
    <!-- 给出该构件在远程仓库的状态。不得在本地项目中设置该元素,因为这是工具自动更新的。有效的值有:none(默认),converted(仓库管理员从 Maven 1 POM转换过来),partner(直接从伙伴Maven 2仓库同步过来),deployed(从Maven 2实例部 署),verified(被核实时正确的和最终的)。-->
    <status/>
  </distributionManagement>
  <!--以值替代名称,Properties可以在整个POM中使用,也可以作为触发条件(见settings.xml配置文件里activation元素的说明)。格式是<name>value</name>。-->
  <properties/>
</project>

pom 详解

13 maven演示

#maven演示地址:http://gitlab.xx.com/projectA/xxx.git
git clone -b v4 http://gitlab.xx.com/projectA/xxx.git
cd projectA
mvn clean package -Dmaven.test.skip=true -P prod  或者 mvn package(第一次打包的方式)
#-P prod 表示将触发prod环境的profile配置,使用profile中id的配置,<profiles>指定的<id>中,可以通过-P进行传递或者赋值。
#clean 表示移除所有上一次构建生成的文件,-Dmaven.test.skip=true表示不执行测试用例,也不编译测试用例类,直接打
#pom配置内容:http://gitlab.xx.com/projectA/xxx.git/pom.xml

最后整理了一下maven的思维导图,希望对大家有所帮助:

 

posted @ 2020-01-16 14:21  wendyw  阅读(715)  评论(0编辑  收藏  举报