美文网首页程序员De天堂程序员@IT·互联网
Maven详解(配置文件,生命周期,常用命令)

Maven详解(配置文件,生命周期,常用命令)

作者: 清枫_小天 | 来源:发表于2017-11-21 18:58 被阅读353次

    当前,JVM生态圈主要的三大构建工具:

    • Apache Ant(带着Ivy)
    • Maven
    • Gradle

    对于刚开始接触这几个工具时,Ant是最清晰的,只要读懂Xml配置文件你就能够理解它干了什么,但是ant文件很容易变的更加复杂。Maven有自己的工程目录规则和内置的构建生成周期,从而使构建文件更加简单。gradle有很多开箱即用的插件,语法更加短小精悍,易于理解。

    在讲解maven之前这里我们先简单比较下Maven和Ant。下面是一个简单的Ant例子。这个例子可以看出我们需要明确的告诉Ant。我们想让他做什么。有一个包含javac任务的编译目标来讲src/main/java的源码编译至target、class目录。需要明确的告诉ant源码在哪里,结果字节码存储在哪里。如何将这些字节码打包成jar文件。

    <?xml version="1.0" encoding="UTF-8"?>
    <project name="test_HelloWorld" basedir="." default="">
         <property name="test" location="test"/>
    
        <target name="init">
                  <mkdir dir="${test}/classess/com/test"/> 
         </target>
    
     <target name="compile" depends="init">
              <javac srcdir="${test}"  destdir="${test}/classess/com/test"/> 
     </target>
    
     <target name="dist" depends="compile">
              <mkdir dir="${test}/classess/com/test/lib"/>
              <jar  jarfile="${test}/classess/com/test/lib/test.jar"  basedir="${test}/classess/com/test"/>
     </target>
    
     <target name="run" depends="compile">
          <java classname="HelloWorld"  classpath="${test}/classess/com/test"/>
     </target> 
    
     <target name="clean">
          <delete dir="${test}/classess"/>
     </target>
    </project>
    

    在Maven中你只需要创建一个简单的pom.xml。将你的源码放在指定目录下。然后运行mvn install 。就能完成和ant同样的事情。从命令行运行mvn install会处理资源文件,编译源代码,运行单元测试,创建一个jar。然后把这个jar安装到本地仓库为其他项目提供重用性。不用做任何修改,运行mvn site然后在target/site目录找到一个Index.html。这个文件链接了javaDoc和一些关于源代码的报告。

    为什么maven运行一个命令就能实现ant定义的一大堆的事情?

    看下面我总结的两者优缺点就明白了。
    Ant

    1. Ant没有正式的约定如一个一般项目的目录结构。你必须明确告诉Ant哪里去找源代码,哪里放置输出。
    2. Ant是程序化,需要明确告诉的告诉Ant做什么,什么时候做。你必须告诉它去编译,然后复制,然后压缩
    3. Ant没有生命周期,你必须定义目标和目标之间的依赖,你必须手工为每个目标附上一个任务序列

    Maven

    1. maven拥有约定,因为你遵循了约定,它已经知道你的源代码在哪里,把字节码放到target/class,然后target生成一个jar文件
    2. maven是声明式的。你需要做的只是创建一个pom.xml 文件然后将源代码放到默认目录。Maven会帮你处理其他事情
    3. maven有一个生命周期,当你运行mvn install的时候被调用,这条命令告诉maven执行一系列的有序步骤。直到到达你指定的生命周期

    接下来我们从以下三个方面讲解Maven

    • maven的pom.xml和Settings.xml解析
    • maven命令
    • maven的生命周期

    maven的Settings.xml解析

    ([配置文件详解]: http://blog.csdn.net/taiyangdao/article/list/11
    对Maven本身行为的定制

    <?xml version="1.0" encoding="UTF-8"?>  
    <settings xsi:schemaLocation="http://maven.apache.org/SETTINGS/1.1.0     http://maven.apache.org/xsd/settings-1.1.0.xsd" xmlns="http://maven.apache.org/SETTINGS/1.1.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">  
    <localRepository/>  
    <interactiveMode/>  
    <offline/>  
    <servers/>  
    <mirrors/>  
    <proxies/>  
    <profiles/>  
    <activeProfiles/>  
    <pluginGroups/>  
    </settings>  
    
    1. localRepository,给出本地库的路径,默认值为${user.home}/.m2/repository。该路径在build服务器上非常重要,项目构建过程中可以直接引用本地库中的通用类库。

    2. interactiveMode,Maven执行过程中是否需要接受用户输入,默认值为true。

    3. usePluginRegistry,是否使用plugin-registry.xml文件管理Maven插件的版本,默认为false。该文件为用户提供了选择,即使用指定版本的Maven插件,而非最新版本的Maven插件。该文件是从Maven 2开始出现的,但是事实上更常用的是在POM中配置Maven插件的版本等参数,所以usePluginRegistry参数往往为false。另外,与settings.xml文件类似,plugin-registry.xml文件也有全局和用户之分。

    4. offline,是否支持离线构建系统,默认值为false。如果build服务器由于网络或者安全等原因不能连接远程库,则该参数设置为true。

    5. pluginGroups,给出Maven插件所在的groupId,一个可能的groupId使用一个<pluginGroup>给出。该参数只是为了简化执行Maven时的参数,如为了执行如下命令:

      mvn org.mortbay.jetty:jetty-maven-plugin:run  
      

    如果在settings.xml文件中配置了如下<pluginGroup>:

      <pluginGroups>  
        <pluginGroup>org.mortbay.jetty</pluginGroup>  
      </pluginGroups>  
    

    则可以直接执行如下命令:

      mvn jetty:run  
    
    1. servers,给出用以下载或部署类库的服务器信息
    2. mirrors,给出指定类库的镜像服务器信息
    3. proxies,给出代理服务器信息
    4. profiles,给出可用的profile,这里的profile类似于POM中的profile,但是只包含activation, repositories, pluginRepositories和properties等与project无关的信息。
    5. activeProfiles,默认采用的profile,可以有多个profile。

    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>
    
    1. 镜像库的id,用以唯一标识该镜像库,默认default
    2. 镜像库的url,即该镜像库访问位置
    3. 镜像库的name,镜像库的名字
    4. 最后,也是最重要的,是要镜像的远程库。例如,如果要镜像Maven的central库,则设置<mirrorOf>central</mirrorOf>

    对于mirrorOf参数,如果该镜像库的目标远程库不止一个,则可以使用 * 表示任意远程库;
    external:*表示任何不在localhost和文件系统中的远程库;
    r1,r2表示r1库或者r2库;
    *,!r1表示除了r1库之外的任何远程库。

    此外,定义镜像库还可以提供 layout(默认default), mirrorOfLayouts(默认default,legacy)。

    Servers

    远程库通常在POM中定义,但是远程库所在的服务器信息,如访问用户名、密码等,往往因为不适合与POM一起发布,所以需要在settings.xml文件中设置。

    <server>
      <id>deploymentRepo</id>
      <username>repouser</username>
      <password>repopwd</password>
      <id>siteServer</id>
      <privateKey>/path/to/private/key</privateKey>
      <passphrase>optional; leave empty if not used.</passphrase>
    </server>
    
    1. id,服务器的ID,Maven在连接一个库或者镜像的时候,通过id匹配要连接的服务器;
    2. username, password,连接服务器所需的认证信息;
    3. privateKey, passphrase,连接服务器所需的认证信息。privateKey默认位于${user.home}/.ssh/id_dsa;
    4. filePermissions, directoryPermissions,库中的文件访问权限和目录访问权限。该值的格式采用3位数字,兼容UNIX/Linux下格式;
    5. configuration,访问服务器辅助要传递的参数,通常不必要;

    Proxies

    <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>
    
    1. id,代理的ID,默认default
    2. active,是否激活该代理,默认true
    3. protocol,代理服务器的协议,默认http
    4. username,password,代理服务器用户名,密码
    5. host,代理服务器的主机
    6. port,代理服务器的端口,默认8080
    7. nonProxyHosts,不使用代理服务器的域名,多个域名使用|分割

    Pom.xml解析

    Maven的pom.xml文件简称POM (Project Object Model),是Maven项目的配置和管理核心。
    pom.xml文件包含大量配置信息,这些信息大致可以分为5类。

    1. POM的模型版本

      <modelVersion>4.0.0</modelVersion>  //说明:在Maven2和Maven3中,只支持4.0.0版本。
      
    2. 基本配置

      <groupId>...</groupId>  
      <artifactId>...</artifactId>  
      <version>...</version>  
      <packaging>...</packaging>  
      <dependencies>...</dependencies>  
      <parent>...</parent>  
      <dependencyManagement>...</dependencyManagement>  
      <modules>...</modules>  
      <properties>...</properties>  
      
    3. Build配置

      <build>...</build>  
      <reporting>...</reporting>
      
    4. 环境配置

      <issueManagement>...</issueManagement>  
      <ciManagement>...</ciManagement>  
      <mailingLists>...</mailingLists>  
      <distributionManagement>...</distributionManagement>  
      <scm>...</scm>  
      <prerequisites>...</prerequisites>  
      <repositories>...</repositories>  
      <pluginRepositories>...</pluginRepositories>  
      <profiles>...</profiles>  
      
    • issueManagement,给出defect tracking system及其访问URL
      • system
      • url
    • ciManagement,给出Continuous Integration Management、其URL和notifier
      • system
      • url
      • notifiers,集成过程中发生事件,以某种方式(如mail)通知开发人员
    • scm,software configuration management
      • connection,用户使用的URI,能够只读地访问版本控制系统
      • developerConnection,开发人员使用URI,能够读写地访问版本控制系统
      • tag,项目当前的tag
      • url,可通过Web浏览器访问的公共网址
    • distributionManagement,构件的发布管理,详情见后续文章
    • prerequisites,POM执行的前提条件,目前只支持对Maven版本的要求
      • maven
    • mailingLists,开发人员或用户的邮件列表
      • name
      • subscribe,订阅地址
      • unsubscribe,取消订阅地址
      • post,POST邮件的目的地址
      • archive,打包的邮件列表历史记录
      • otherArchives,镜像打包的邮件列表历史记录
    1. 其他信息

      <name>...</name>  
      <description>...</description>  
      <url>...</url>  
      <inceptionYear>...</inceptionYear>  
      <licenses>...</licenses>  
      <organization>...</organization>  
      <developers>...</developers>  
      <contributors>...</contributors>  
      
    • name,项目的名称代号

    • description,项目的说明

    • url,项目的官网URL

    • inceptionYear,项目的开发年份

    • licenses,项目使用的License。其中可以包含多个license,license具体又包含如下子属性

      • name,license的名称
      • url,license可访问的URL地址
      • distribution,license发布的方式。repo表示可以直接从Maven库下载,manual表示必须手工安装
      • comments,对license的说明
    • organization,包含组织的name,组织的官网url

    • developers,其中的developer包含id, name, email, url, organization, organizationUrl, roles, timezone, properties属性(properties是可以自定义的各种必要属性)

    • contributors,其中的contributor包含与developer基本相同的属性,除了没有id属性之外

    packaging

    packaging给出了项目的打包类型,即作为项目的发布形式,其可能的类型。在Maven 3中,其可用的打包类型如下:
    • jar,默认类型
    • war
    • ejb
    • ear
    • rar
    • par
    • pom
    • maven-plugin

    multi-modules

    Maven 3支持Maven项目的多模块(multi-modules)结构。这样的Maven项目也被称为聚合项目,通常由一个父模块和若干个子模块构成。
    其中,父模块必须以pom打包类型,同时以<modules>给出所有的子模块。父模块的POM示例(其中的每个module,都是另外一个Maven项目)

     ...  
     <packaging>pom</packaging>  
     <modules>  
       <module>my-frontend-project</module>  
       <module>my-service-project</module>  
       <module>my-backend-project</module>  
     </modules>  
     ... 
    

    Maven项目的继承

    Maven项目之间不仅存在多模块的聚合关系,而且Maven项目之间还可以存在相互继承的关系。Maven项目之间的继承关系通过<parent>表示,在子Maven项目的POM中配置示例如下:

    <parent>  
    <groupId>com.ericsson.jcat</groupId>  
    <artifactId>jcat-bundle</artifactId>  
    <version>2.0</version>  
    <relativePath>../jcat-bundle</relativePath>  
    </parent>  
    

    其中的relativePath给出父项目相对于子项目的路径,这样在构件子项目时首先从该相对路径查找父项目,如果没有才会从本地库或进而远程库中查找父项目。

    在子项目中,能够继承父项目的如下配置:
    • dependencies
    • developers
    • contributors
    • plugin lists
    • reports lists
    • plugin executions with matching ids
    • plugin configuration

    dependencies

    Maven项目的构建往往要依赖于第三方的类库。通过<dependencies>可以给出Maven项目所依赖的第三方类库

    <dependencies>
        <dependency>
            <groupId>org.gitlab</groupId>
            <artifactId>java-gitlab-api</artifactId>
            <version>1.2.6</version>
        </dependency>
    </dependencies>
    
    • 对于一个依赖<dependency>,首先要给出被依赖的Maven构件(被依赖的只能是Maven构件)的具体标识信息,如groupId、artifactId和version(可以是一个范围)。为了进一步区分Maven构件的内容(如source、bin和doc),往往还会给出Maven构件的classifier。
    • type,打包类型,默认jar
    • scope,被依赖的Maven构件在classpath中的可访问范围
      • compile,默认值,被依赖的Maven构件在compile、runtime和test的时候都可以在classpath中找到
      • provided,被依赖的Maven构件在compile和test的时候都可以在classpath中找到,在runtime的时候由JDK或容器提供
      • system,被依赖的Maven构件在compile和test的时候都可以在classpath中找到,在runtime的时候必须显式将JAR加入到classpath中
      • runtime,被依赖的Maven构件在runtime和test的时候都可以在classpath中找到,在compile时不是必须的
      • test,被依赖的Maven构件在test的时候可以在classpath中找到,在compile和runtime时不是必须的
    • systemPath,只有当<scope>system</scope>时才设置,否则构建时会报错。该值必须是一个绝对路径,可以通过环境变量给出具体的绝对路径
    • optional,当前Maven项目的构件被其他项目依赖,此处被依赖的Maven构件相对于其他项目来说是不必须的
    • exclusions,将一个被依赖的Maven构件中的部分类库,从classpath中去掉

    Properties

    在Maven的pom.xml文件中,<properties>用于定义全局变量,在POM中通过${property_name}的形式引用变量的值。
    POM中的全局变量可以分为如下5种类型:
    • 系统Shell的环境变量env.property_name,如${env.PATH}表示引用当前系统的PATH变量值,注意这里的PATH必须都是大写。
    • Java System Properties,即Java属性文件,如${java.home}
    • project.property_name,直接引用POM中的元素值,如${project.version}表示引用<project><version>1.0</version></project>中的1.0
    • settings.property_name,直接引用settings.xml中的元素值,如${settings.offline}表示引用<settings><offline>false</offline></settings>中的false
    • property_name,直接访问<properties>中已经定义的变量值,如${myVar}表示引用<properties><myVar>myvalue</myVar></properies>中的myvalue

    build

    <resources>

    资源往往不是代码,无需编译,而是一些properties或XML配置文件,构建过程中会往往会将资源文件从源路径复制到指定的目标路径。

    <plugins>

    <plugins>给出构建过程中所用到的插件。

    <pluginManagement>

    在<build>中,<pluginManagement>与<plugins>并列,两者之间的关系类似于<dependencyManagement>与<dependencies>之间的关系。<pluginManagement>中也配置<plugin>,其配置参数与<plugins>中的<plugin>完全一致。只是,<pluginManagement>往往出现在父项目中,其中配置的<plugin>往往通用于子项目。子项目中只要在<plugins>中以<plugin>声明该插件,该插件的具体配置参数则继承自父项目中<pluginManagement>对该插件的配置,从而避免在子项目中进行重复配置。

    Project Build特有的<extensions>

    <extensions>是执行构建过程中可能用到的其他工具,在执行构建的过程中被加入到classpath中。
    也可以通过<extensions>激活构建插件,从而改变构建的过程。
    通常,通过<extensions>给出通用插件的一个具体实现,用于构建过程。

    reporting

    <reporting>中的配置作用于Maven的site阶段,用于生成报表。<reporting>中也可以配置插件<plugins>,并通过一个<plugin>的<reportSet>为该插件配置参数。注意,对于同时出现在<build>和<reporting>中的插件,<reporting>中对该插件的配置也能够在构建过程中生效,即该插件的配置是<build>和<reporting>中的配置的合并。

    Profiles

    在Maven项目中,profile是根据不同的构件环境,对构建(build)过程进行动态配置的手段。
    可以通过pom.xml定义多个profile,也可以通过settings.xml文件定义多个profile。对于一个profile,如果同时在pom.xml和settings.xml中配置,则settings.xml中的配置优先。
    settings.xml中的profile只能配置如下元素:

    • id
    • activation
    • repositories
    • pluginRepositories
    • properties
    pom.xml中的profile能配置如下元素:

    • id
    • activation
    • repositories
    • pluginRepositories
    • properties
    • build
    • modules
    • dependencies
    • dependencyManagement
    • repositories
    • pluginRepositories
    • distributionManagement
    • reporting
    在每个profile中,都有一个<activation>给出当前profile被激活的环境条件,其中给出的任何一个条件满足即激活该profile

    Maven生命周期

    http://maven.apache.org/guides/introduction/introduction-to-the-lifecycle.html(官网解说)

    Maven强大的一个重要的原因是它有一个十分完善的生命周期模型(lifecycle),这个生命周期可以从两方面来理解,第一,顾名思义,运行Maven的每个步骤都由它来定义的,这种预定义的默认行为使得我们使用Maven变得简单,相比而言,Ant的每个步骤都要你手工去定义。第二,这个模型是一种标准,在不同的项目中,使用Maven的接口是一样的,这样就不用去仔细理解每个项目的构建了,一般情况下,mvn clean install 这样的命令是通用的。

    Maven有三套相互独立的生命周期,请注意这里说的是“三套”,而且“相互独立”,很多人容易将Maven的生命周期看成一个整体,其实不然。这三套生命周期分别是:

    • Clean Lifecycle 在进行真正的构建之前进行一些清理工作。
    • Default Lifecycle 构建的核心部分,编译,测试,打包,部署等等。
    • Site Lifecycle 生成项目报告,站点,发布站点。

    每套生命周期都由一组阶段(Phase)组成,我们平时在命令行输入的命令总会对应于一个特定的阶段。比如,运行mvn clean ,这个的clean是Clean生命周期的一个阶段。

    Clean生命周期一共包含了三个阶段:

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

    mvn clean 中的clean就是上面的clean,在一个生命周期中,运行某个阶段的时候,它之前的所有阶段都会被运行,也就是说,mvn clean 等同于 mvn pre-clean clean ,如果我们运行 mvn post-clean ,那么 pre-clean,clean 都会被运行。这是Maven很重要的一个规则,可以大大简化命令行的输入。

    下面看一下Site生命周期的各个阶段:

    • pre-site 执行一些需要在生成站点文档之前完成的工作
    • site 生成项目的站点文档
    • post-site 执行一些需要在生成站点文档之后完成的工作,并且为部署做准备
    • site-deploy 将生成的站点文档部署到特定的服务器上
    这里经常用到的是site阶段和site-deploy阶段,用以生成和发布Maven站点,这可是Maven相当强大的功能,Manager比较喜欢,文档及统计数据自动生成,很好看。

    Maven的最重要的Default生命周期

    • validate
    • generate-sources
    • process-sources
    • generate-resources
    • process-resources 复制并处理资源文件,至目标目录,准备打包。
    • compile 编译项目的源代码。
    • process-classes
    • generate-test-sources
    • process-test-sources
    • generate-test-resources
    • process-test-resources 复制并处理资源文件,至目标测试目录。
    • test-compile 编译测试源代码。
    • process-test-classes
    • test 使用合适的单元测试框架运行测试。这些测试代码不会被打包或部署。
    • prepare-package
    • package 接受编译好的代码,打包成可发布的格式,如 JAR 。
    • pre-integration-test
    • integration-test
    • post-integration-test
    • verify
    • install 将包安装至本地仓库,以让其它项目依赖。
    • deploy 将最终的包复制到远程的仓库,以让其它开发人员与项目共享。

    记住,运行任何一个阶段的时候,它前面的所有阶段都会被运行,这也就是为什么我们运行mvn install 的时候,代码会被编译,测试,打包。

    Maven常用命令

    Maven参数

    • -D 传入属性参数
    • -P 使用pom中指定的配置
    • -e 显示maven运行出错的信息
    • -o 离线执行命令,即不去远程仓库更新包
    • -X 显示maven允许的debug信息
    • -U 强制去远程参考更新snapshot包

    Maven常用命令

    1. 创建Maven的普通java项目:
      mvn archetype:create -DgroupId=packageName -DartifactId=projectName

    2. 创建Maven的Web项目:
      mvn archetype:create -DgroupId=packageName -DartifactId=webappName-DarchetypeArtifactId=maven-archetype-webapp

    3. 编译源代码:mvn compile

    4. 编译测试代码:mvn test-compile

    5. 运行测试:mvn test

    6. 产生site:mvn site

    7. 打包:mvn package

    8. 在本地Repository中安装jar:mvn install

    9. 清除产生的项目:mvn clean

    10. 生成eclipse项目:mvn eclipse:eclipse

    11. 生成idea项目:mvn idea:idea

    12. 组合使用goal命令,如只打包不测试:mvn -Dtest package

    13. 编译测试的内容:mvn test-compile

    14. 只打jar包: mvn jar:jar

    15. 只测试而不编译,也不测试编译:

       mvn test -skipping compile -skipping test-compile
       ( -skipping 的灵活运用,当然也可以用于其他组合命令) 
      
    16. 清除eclipse的一些系统设置:mvn eclipse:clean
      ps:一般使用情况是这样,首先通过cvs或svn下载代码到本机,然后执行mvn eclipse:eclipse生成ecllipse项目文件,然后导入到eclipse就行了;修改代码后执行mvn compile或mvn test检验,也可以下载eclipse的maven插件。

    17. mvn -version/-v 显示版本信息

    18. mvn archetype:generate 创建mvn项目

    19. mvn archetype:create -DgroupId=com.oreilly -DartifactId=my-app 创建mvn项目

    20. mvn package 生成target目录,编译、测试代码,生成测试报告,生成jar/war文件

    21. mvn jetty:run 运行项目于jetty上,

    22. mvn compile 编译

    23. mvn test 编译并测试

    24. mvn clean 清空生成的文件

    25. mvn site 生成项目相关信息的网站

    26. mvn -e 显示详细错误 信息.

    27. mvn validate 验证工程是否正确,所有需要的资源是否可用。

    28. mvn test-compile 编译项目测试代码。 。

    29. mvn integration-test 在集成测试可以运行的环境中处理和发布包。

    30. mvn verify 运行任何检查,验证包是否有效且达到质量标准。

    31. mvn generate-sources 产生应用需要的任何额外的源代码,如xdoclet。

    发布第三方Jar到本地库中:
    mvn install:install-file -DgroupId=com -DartifactId=client -Dversion=0.1.0 -Dpackaging=jar -Dfile=d:\client-0.1.0.jar
    -DdownloadSources=true
    -DdownloadJavadocs=true

    相关文章

      网友评论

      本文标题:Maven详解(配置文件,生命周期,常用命令)

      本文链接:https://www.haomeiwen.com/subject/agmivxtx.html