Maven 配置文件 生命周期 常用命令详解
当前,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
- ant没有正式的约定如一个一般项目的目录结构。你必须明确告诉ant哪里去找源代码,哪里放置输出。
- ant是程序化,需要明确告诉的告诉ant做什么,什么时候做。你必须告诉它去编译,然后复制,然后压缩
- ant没有生命周期,你必须定义目标和目标之间的依赖,你必须手工为每个目标附上一个任务序列
maven
- maven拥有约定,因为你遵循了约定,它已经知道你的源代码在哪里,把字节码放到target/class,然后target生成一个jar文件
- maven是声明式的。你需要做的只是创建一个pom.xml 文件然后将源代码放到默认目录。maven会帮你处理其他事情
- maven有一个生命周期,当你运行mvn install的时候被调用,这条命令告诉maven执行一系列的有序步骤。直到到达你指定的生命周期
接下来我们从以下三个方面讲解maven
- maven的pom.xml和settings.xml解析
- maven命令
- maven的生命周期
maven的settings.xml解析
对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>
- localrepository,给出本地库的路径,默认值为${user.home}/.m2/repository。该路径在build服务器上非常重要,项目构建过程中可以直接引用本地库中的通用类库。
- interactivemode,maven执行过程中是否需要接受用户输入,默认值为true。
- usepluginregistry,是否使用plugin-registry.xml文件管理maven插件的版本,默认为false。该文件为用户提供了选择,即使用指定版本的maven插件,而非最新版本的maven插件。该文件是从maven 2开始出现的,但是事实上更常用的是在pom中配置maven插件的版本等参数,所以usepluginregistry参数往往为false。另外,与settings.xml文件类似,plugin-registry.xml文件也有全局和用户之分。
- offline,是否支持离线构建系统,默认值为false。如果build服务器由于网络或者安全等原因不能连接远程库,则该参数设置为true。
- 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
servers,给出用以下载或部署类库的服务器信息
mirrors,给出指定类库的镜像服务器信息
proxies,给出代理服务器信息
profiles,给出可用的profile,这里的profile类似于pom中的profile,但是只包含activation, repositories, pluginrepositories和properties等与project无关的信息。
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>
- 镜像库的id,用以唯一标识该镜像库,默认default
- 镜像库的url,即该镜像库访问位置
- 镜像库的name,镜像库的名字
- 最后,也是最重要的,是要镜像的远程库。例如,如果要镜像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>
id,服务器的id,maven在连接一个库或者镜像的时候,通过id匹配要连接的服务器;
username, password,连接服务器所需的认证信息;
privatekey, passphrase,连接服务器所需的认证信息。privatekey默认位于${user.home}/.ssh/id_dsa;
filepermissions, directorypermissions,库中的文件访问权限和目录访问权限。该值的格式采用3位数字,兼容unix/linux下格式;
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>
- id,代理的id,默认default
- active,是否激活该代理,默认true
- protocol,代理服务器的协议,默认http
- username,password,代理服务器用户名,密码
- host,代理服务器的主机
- port,代理服务器的端口,默认8080
- 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,镜像打包的邮件列表历史记录
5.其他信息
<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}的形式引用变量的值。
maven生命周期
(官网解说)
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常用命令
创建maven的普通java项目:
mvn archetype:create -dgroupid=packagename -dartifactid=projectname
创建maven的web项目:
mvn archetype:create -dgroupid=packagename -dartifactid=webappname-darchetypeartifactid=maven-archetype-webapp
编译源代码:mvn compile
编译测试代码:mvn test-compile
运行测试:mvn test
产生site:mvn site
打包:mvn package
在本地repository中安装jar:mvn install
清除产生的项目:mvn clean
生成eclipse项目:mvn eclipse:eclipse
生成idea项目:mvn idea:idea
组合使用goal命令,如只打包不测试:mvn -dtest package
编译测试的内容:mvn test-compile
只打jar包: mvn jar:jar
只测试而不编译,也不测试编译:
mvn test -skipping compile -skipping test-compile
( -skipping 的灵活运用,当然也可以用于其他组合命令)
清除eclipse的一些系统设置:mvn eclipse:clean
ps:一般使用情况是这样,首先通过cvs或svn下载代码到本机,然后执行mvn eclipse:eclipse生成ecllipse项目文件,然后导入到eclipse就行了;修改代码后执行mvn compile或mvn test检验,也可以下载eclipse的maven插件。
mvn -version/-v 显示版本信息
mvn archetype:generate 创建mvn项目
mvn archetype:create -dgroupid=com.oreilly -dartifactid=my-app 创建mvn项目
mvn package 生成target目录,编译、测试代码,生成测试报告,生成jar/war文件
mvn jetty:run 运行项目于jetty上,
mvn compile 编译
mvn test 编译并测试
mvn clean 清空生成的文件
mvn site 生成项目相关信息的网站
mvn -e 显示详细错误 信息.
mvn validate 验证工程是否正确,所有需要的资源是否可用。
mvn test-compile 编译项目测试代码。 。
mvn integration-test 在集成测试可以运行的环境中处理和发布包。
mvn verify 运行任何检查,验证包是否有效且达到质量标准。
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 配置文件 生命周期 常用命令详解,希望对大家有所帮助