首页 > Java > 工具篇 > 项目管理工具:Maven教程
2014
10-12

项目管理工具:Maven教程

三、Maven依赖管理

1、Maven坐标

Maven中的依赖管理是自动的,在使用到某个依赖时,Maven会根据pom.xml中配置的依赖的坐标去查找该依赖。Maven坐标的三要素如下:

  • groupId:指定当前Maven项目隶属的公司或组织(一般情况)
  • artifactId:当前项目名
  • version:定义当前项目的当前版本

如果需要将该项目作为自己项目中的依赖时,就需要指定这三个元素。

2、依赖作用范围

在pom中引入的依赖(jar包),可以指定其作用范围,如上面例子中在引入junit时配置的<scope>test</scope>,指定junit在测试时才起作用,即junit只会在执行 compiler:testCompile and surefire:test 目标的时候才会被加到 classpath 中,在执行 compiler:compile 目标时是拿不到 junit 的。

常见的依赖范围如下:

项目管理工具:Maven教程4105

  • compile:scope的默认值,任何时候都会被包含在classpath中。即对于编译,测试,运行三种classpath都有效
  • test:测试依赖范围。只对于测试classpath有效
  • provided:对于JDK或者容器已经提供的Jar包,可以设置对应依赖的scope为provided,例如servlet-api。对于编译,测试的classpath都有效,但对于运行无效。
  • runtime:运行时提供。例如 jdbc驱动

3、继承

如果本地有多个项目都使用了同样的依赖,在需要在每个项目的pom.xml中配置相同的内容,此时可以使用继承消除重复:把相同的配置提取出来供其他项目继承。

1)父工程设置为被继承:<packaging>pom</packaging>

2)子工程继承父工程:通过parent元素配置父工程的坐标

<parent>
	<groupId> …</groupId>
	<artifactId> … </artifactId>
	<version> … </version>
</parent>

前提:父工程在本地仓库中。

关于Maven中继承的具体配置使用时再去查。

四、Maven插件

前面演示了使用Eclipse新建一个Maven工程,除此之外,还可以使用『mvn archetype:generate』来生成一个Maven项目。

这里generate表示目标(goal),archetype是包含这个目标的插件名称,插件目标通常会写成 pluginId:goalId,这个命令的意思是告诉 maven 执行 archetype 插件的 generate 目标。

一个目标是一个工作单元,而插件是一系列拥有共同目的(general common purpose)的目标的集合。比如说Jar插件,Compiler插件,Surefire插件等。从看名字就能知道,Jar 插件包含建立Jar文件的目标, Compiler 插件包含编译源代码和单元测试代码的目标,Surefire 则是运行单元测试的插件。

看到这里,估计你能明白了,mvn 本身不会做太多的事情,它不知道怎么样编译或者怎么样打包。它把构建的任务交给插件去做。插件定义了常用的构建逻辑,能够被重复利用。这样做的好处是,一旦插件有了更新,那么所有的 maven 用户都能得到更新。后面会具体讲这种关系。

五、生命周期和阶段

生命周期指项目的构建过程,它包含了一系列的有序的阶段 (phase),而一个阶段就是构建过程中的一个步骤。

1、三套生命周期

Maven有三套相互独立的生命周期,请注意这里说的是“三套”,而且“相互独立”,这三套生命周期分别是:

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

再次强调一下它们是相互独立的,你可以仅仅调用clean来清理工作目录,仅仅调用site来生成站点。当然你也可以直接运行 mvn clean install site运行所有这三套生命周期。

2、生命周期和阶段(☆)

每套生命周期都由一组阶段(Phase)组成,我们平时在命令行输入的命令总会对应于一个特定的阶段,比如mvn clean ,这个的clean是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很重要的一个规则,可以大大简化命令行的输入。

3、默认生命周期(Default Lifecycle)

常见阶段:

  • validate:验证项目是否正确,所有必须的信息是否可用。
  • compile:编译项目的源码(生成maven-demo/target目录存放 .class文件)
  • test:使用单元测试框架对编译后的源码进行测试 , 测试代码不会被打包或部署。
  • package:接受编译好的代码,打包成可发布的格式,如JAR。通常使用mvn package -Dmaven.test.skip=true用于跳过测试。
  • verify:运行任何检查,验证包是否有效且达到质量标准。
  • install:将包安装到Maven本地仓库,供本地其他Maven项目使用。
  • deploy:将最终的包发布到远程仓库(如Tomcat、JBoss),供其他开发人员和Maven项目使用。

4、Site生命周期

常见阶段:

  • site:生成项目的站点文档
  • site-deploy:将生成的站点文档部署到特定的服务器上

5、生命周期阶段和插件目标之间的关系

Maven的生命周期其实是它对所有的构建过程进行总结之后的一套高度抽象过程。它类似于接口,只定义规范,具体的实现细节则交给Maven的各种强大的插件。Maven提供了一系列的默认插件,如编译阶段对应maven-compiler-plugin插件。

生命周期的阶段(phase)最终会被映射到底层的目标(goal)。每个阶段执行的具体目标也依赖于项目的打包类型,例如,如果项目类型是一个JAR包的话,package 映射到的目标是 jar:jar ,而如果项目类型是 WAR 的话,执行的是 war:war。

常见的 phase-goal 之间的映射如下:

  • compile阶段 – compiler:compile
  • test-compile阶段 – compiler:testCompile
  • test阶段 – surefile:test
  • package阶段 – jar:jar 或 war:war

六、其他问题

1、POM文件中可以使用的6类属性值

1)内置属性:Maven预定义,用户可以直接使用

  • ${basedir}表示项目根目录,即包含pom.xml文件的目录;
  • ${version}表示项目版本;
  • ${project.basedir}同${basedir};
  • ${project.baseUri}表示项目文件地址;
  • ${maven.build.timestamp}表示项目构件开始时间;
  • ${maven.build.timestamp.format}表示属性${maven.build.timestamp}的展示格式,默认值为yyyyMMdd-HHmm,可自定义其格式,其类型可参考java.text.SimpleDateFormat。用法如下:
<properties>
<maven.build.timestamp.format>yyyy-MM-dd HH:mm:ss</maven.build.timestamp.format>
</properties>

2)POM属性:使用pom属性可以引用到pom.xml文件对应元素的值

  • ${project.build.directory}表示主源码路径;
  • ${project.build.sourceEncoding}表示主源码的编码格式;
  • ${project.build.sourceDirectory}表示主源码路径;
  • ${project.build.finalName}表示输出文件名称;
  • ${project.version}表示项目版本,与${version}相同;

3)自定义属性:在pom.xml文件的<properties>标签下定义的Maven属性

<project>
  <properties>
    <my.pro>abc</my.pro>
  </properties>
</project>

在其他地方使用${my.pro}使用该属性值。

4)settings.xml文件属性:与pom属性同理,用户使用以settings.开头的属性引用settings.xml文件中的XML元素值

  • ${settings.localRepository}表示本地仓库的地址;

5)Java系统属性:所有的Java系统属性都可以使用Maven属性引用

使用mvn help:system命令可查看所有的Java系统属性;System.getProperties()可得到所有的Java属性;

  • ${user.home}表示用户目录;

6)环境变量属性:所有的环境变量都可以用以env.开头的Maven属性引用

使用mvn help:system命令可查看所有环境变量;

  • ${env.JAVA_HOME}表示JAVA_HOME环境变量的值;

2、Maven仓库

当第一次运行 maven 命令的时候,你需要 Internet 连接,因为它要从 maven 默认的远程库(http://repo1.maven.org/maven2) 下载一些文件。这个远程库有 maven 的核心插件和可供下载的 jar 文件。

Java工程中使用的依赖可能存在于下面的仓库中(仓库的分类):

1)本地仓库:在上面的HelloMaven例子中用的仓库就是本地仓库。运行mvn install命令能把我们自己的项目安装到本地库

2)远程仓库:

① 中央仓库:Maven默认的远程仓库

② 私服:是一种特殊的远程仓库,它是架设在局域网内的仓库。关于使用Nexus搭建私服和使用私服,用到时再去查询。


留下一个回复

你的email不会被公开。