Maven入门指南

来源:互联网 发布:儿童dna数据库有用吗 编辑:程序博客网 时间:2024/06/05 17:38

本指南旨在作为第一次与Maven合作的人员的参考,但也旨在作为具有独立参考和适用于常见用例的解决方案的食谱。对于第一次使用者,建议您按顺序浏览材料。对于更熟悉Maven的用户,本指南将为您提供快速解决方案。在这一点上假设您已经下载了Maven并在本地机器上安装了Maven。如果还没有这样做,请参阅下载和安装说明。

好的,所以你现在安装了Maven,我们准备好了。在我们进入我们的例子之前,我们将简要介绍一下Maven是什么,以及如何帮助您与团队成员进行日常工作和协作。当然,Maven将为小型项目工作,但是Maven通过允许团队成员专注于项目的利益相关者需要,帮助团队更有效地运作。您可以将构建基础架构保留到Maven!

  • 什么是Maven?
  • Maven如何有利于我的开发过程?
  • 如何设置Maven?
  • 我如何制作我的第一个Maven项目?
  • 如何编译我的应用程序源?
  • 如何编译测试源并运行我的单元测试?
  • 如何创建JAR并将其安装在本地存储库中?
  • 什么是SNAPSHOT版本?
  • 如何使用插件?
  • 如何为我的JAR添加资源?
  • 如何过滤资源文件?
  • 如何使用外部依赖关系?
  • 如何在我的远程存储库中部署我的jar?
  • 如何创建文档?
  • 如何建立其他类型的项目?
  • 如何一次构建多个项目?

什么是MAVEN ?

乍一看,Maven似乎有许多事情,但简而言之,Maven试图将模式应用于项目的构建基础设施,以通过提供使用最佳实践的明确途径来提高理解和生产力。Maven本质上是一个项目管理和理解工具,因此提供了一种帮助管理的方法:

  • 构建
  • 文档
  • 报告
  • 依赖
  • 供应链管理系统
  • 发布
  • 分配

如果你想要更多的Maven背景信息,你可以查看“Maven的哲学”和“ Maven 的历史”。现在我们来看看用户如何从使用Maven中获益。

Maven如何有利于我的开发过程?

Maven可以通过采用标准的惯例和实践为您的构建过程提供好处,从而加快开发周期,同时帮助您实现更高的成功率。

现在,我们已经涵盖了Maven的一些历史和目的,让我们进一步了解一些真正的例子,让你和Maven一起运行!

如何设置MAVEN?

Maven的默认值通常是足够的,但是如果您需要更改缓存位置或者在HTTP代理之后,您将需要创建配置。有关详细信息,请参阅配置Maven指南。

如何制作第一个MAVEN项目?

我们要跳过创建你的第一个Maven项目!要创建我们的第一个Maven项目,我们将使用Maven的原型机制。原型被定义为原始图案或模型,从该图案或模型可以制作同一种类的所有其他东西。在Maven中,原型是一个项目的模板,与一些用户输入相结合,以生成针对用户要求定制的工作Maven项目。我们将向您展示原型机构的工作原理,但如果您想了解更多关于原型的信息,请参阅我们的原型简介。

在创建你的第一个项目!为了创建最简单的Maven项目,请从命令行执行以下操作:

  1. mvn-B archetype:generate \
  2. -DarchetypeGroupId=org.apache.maven.archetypes \
  3. -DgroupId=com.mycompany.app \
  4. -DartifactId=my-app
一旦你执行了这个命令,你会注意到一些事情发生了。首先,您将注意到,为新项目创建了一个名为my-app的目录,此目录包含一个名为pom.xml的文件,该文件应如下所示:

  1. <projectxmlns="http://maven.apache.org/POM/4.0.0"
  2. xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  3. xsi:schemaLocation="http://maven.apache.org/POM/4.0.0
  4. http://maven.apache.org/xsd/maven-4.0.0.xsd">
  5. <modelVersion>4.0.0</modelVersion>
  6. <groupId>com.mycompany.app</groupId>
  7. <artifactId>my-app</artifactId>
  8. <packaging>jar</packaging>
  9. <version>1.0-SNAPSHOT</version>
  10. <name>Maven Quick Start Archetype</name>
  11. <url>http://maven.apache.org</url>
  12. <dependencies>
  13. <dependency>
  14. <groupId>junit</groupId>
  15. <artifactId>junit</artifactId>
  16. <version>4.11</version>
  17. <scope>test</scope>
  18. </dependency>
  19. </dependencies>
  20. </project>

pom.xml包含此项目的项目对象模型(POM)。POM是Maven的基本工作单位。这很重要,因为Maven本质上是以项目为中心的,因为一切都围绕一个项目的概念。简而言之,POM包含有关您的项目的所有重要信息,并且基本上是一站式购物,以查找与您的项目相关的任何内容。了解POM是重要的,鼓励新用户参考POM简介。

这是一个非常简单的POM,但仍然显示每个POM包含的关键元素,所以让我们走过每一个,以熟悉POM要点:

  • project 这是所有Maven pom.xml文件中的顶级元素。
  • modelVersion此元素指示该POM正在使用的对象模型的版本。模型本身的版本很少变化,但是如果Maven开发人员认为有必要更改模型,那么为了确保使用的稳定性是必须的。
  • groupId此元素指示创建项目的组织或组的唯一标识符。groupId是项目的关键标识符之一,通常基于您组织的完全限定域名。例如,org.apache.maven.plugins是所有Maven插件的指定的groupId。
  • artifactId此元素指示此项目生成的主要工件的唯一基本名称。项目的主要工件通常是JAR文件。诸如源码包之类的辅助工件也会使用artifactId作为其最终名称的一部分。由Maven生成的典型工件将具有<artifactId> - <version>。<extension>(例如myapp-1.0.jar)的形式。
  • packaging 此元素指示此工件要使用的包类型(例如JAR,WAR,EAR等)。这不仅意味着如果生成的工件是JAR,WAR或EAR,但也可以指示在构建过程中使用的特定生命周期。(生命周期是我们将在指南中进一步处理的一个主题,现在,请记住,指定的项目包装可以在定制构建生命周期中发挥作用。)包装元素的默认值为JAR所以你不必为大多数项目指定。
  • version此元素指示项目生成的工件的版本。Maven可以帮助您进行版本管理,您将经常在一个版本中看到SNAPSHOT指示符,这表明项目处于开发状态。我们将在本指南中讨论快照的使用及其进一步工作。
  • name此元素指示用于项目的显示名称。这通常用在Maven生成的文档中。
  • url此元素指示项目的网站可以在哪里找到。这通常用在Maven生成的文档中。
  • description此元素提供了您的项目的基本描述。这通常用在Maven生成的文档中。

有关可用于POM的元素的完整参考,请参阅我们的POM参考。现在让我们回到手头的项目。


在您的第一个项目的原型生成之后,您还将注意到已创建以下目录结构:

  1. my-app
  2. |-- pom.xml
  3. `-- src
  4. |-- main
  5. | `-- java
  6. |`-- com
  7. | `-- mycompany
  8. |`-- app
  9. | `--App.java
  10. `-- test
  11. `-- java
  12. `-- com
  13. `-- mycompany
  14. `-- app
  15. `--AppTest.java

如您所见,从原型创建的项目具有POM,应用程序源的源代码树和测试源的源代码树。这是Maven项目的标准布局(应用程序源位于$${basedir}/src/main/java,测试源驻留在${basedir}/src/test/java,其中$ {basedir}表示包含pom的目录.xml)。

如果要手动创建一个Maven项目,这是我们建议使用的目录结构。这是一个Maven大会,要了解更多信息,您可以阅读我们的标准目录布局简介。

现在我们有一个POM,一些应用程序源和一些测试源,你可能会问...

如何编译我们的程序源?

转到由archetype创建pom.xml的目录:generate并执行以下命令来编译应用程序源:

  1. mvn compile

执行该命令后,您将看到如下所示的输出:

  1. [INFO]----------------------------------------------------------------------------
  2. [INFO]BuildingMavenQuickStartArchetype
  3. [INFO] task-segment:[compile]
  4. [INFO]----------------------------------------------------------------------------
  5. [INFO] artifact org.apache.maven.plugins:maven-resources-plugin: \
  6. checking for updatesfrom central
  7. ...
  8. [INFO] artifact org.apache.maven.plugins:maven-compiler-plugin: \
  9. checkingfor updatesfrom central
  10. ...
  11. [INFO][resources:resources]
  12. ...
  13. [INFO][compiler:compile]
  14. Compiling1 source file to<dir>/my-app/target/classes
  15. [INFO]----------------------------------------------------------------------------
  16. [INFO] BUILD SUCCESSFUL
  17. [INFO]----------------------------------------------------------------------------
  18. [INFO]Total time:3 minutes54 seconds
  19. [INFO]Finished at:FriSep2315:48:34 GMT-05:002005
  20. [INFO]FinalMemory:2M/6M
  21. [INFO]----------------------------------------------------------------------------

第一次执行(或任何其他)命令时,Maven将需要下载其完成命令所需的所有插件和相关依赖项。从一个干净安装的Maven,这可能需要相当长的一段时间(在上面的输出,花了差不多4分钟)。如果再次执行该命令,Maven现在将拥有所需的内容,因此不需要下载任何新内容,并能够更快地执行命令。

从输出可以看出,编译的类被放置在$ {basedir} / target / classes中,这是Maven使用的另一个标准约定。所以,如果你是一个敏锐的观察者,你会注意到,通过使用标准约定,上面的POM非常小,你不必明确地告诉Maven你的任何来源是什么,或输出应该在哪里。遵循标准的Maven约定,您可以用很少的精力完成很多工作!就像一个偶然的比较,让我们来看看你可能在 Ant 做了什么来完成同样的事情。

现在,这只是编译单个应用程序源树,并且显示的Ant脚本与上面显示的POM大致相同。但是,我们还可以看到我们可以用简单的POM做多少事情!

如何编译测试源并运行测试单元

现在,您正在成功编译应用程序的源码,现在您已经有一些要编译和执行的单元测试(因为每个程序员总是写入并执行单元测试*微调微调wink wink *)。

执行以下命令:

  1. mvn test
执行该命令后,您将看到如下所示的输出:

  1. [INFO]----------------------------------------------------------------------------
  2. [INFO]BuildingMavenQuickStartArchetype
  3. [INFO] task-segment:[test]
  4. [INFO]----------------------------------------------------------------------------
  5. [INFO] artifact org.apache.maven.plugins:maven-surefire-plugin: \
  6. checking for updatesfrom central
  7. ...
  8. [INFO][resources:resources]
  9. [INFO][compiler:compile]
  10. [INFO]Nothing to compile- all classes are up to date
  11. [INFO][resources:testResources]
  12. [INFO][compiler:testCompile]
  13. Compiling1 source file to C:\Test\Maven2\test\my-app\target\test-classes
  14. ...
  15. [INFO][surefire:test]
  16. [INFO]Setting reports dir: C:\Test\Maven2\test\my-app\target/surefire-reports
  17.  
  18. -------------------------------------------------------
  19. T E S T S
  20. -------------------------------------------------------
  21. [surefire]Running com.mycompany.app.AppTest
  22. [surefire]Tests run:1,Failures:0,Errors:0,Time elapsed:0 sec
  23.  
  24. Results:
  25. [surefire]Tests run:1,Failures:0,Errors:0
  26.  
  27. [INFO]----------------------------------------------------------------------------
  28. [INFO] BUILD SUCCESSFUL
  29. [INFO]----------------------------------------------------------------------------
  30. [INFO]Total time:15 seconds
  31. [INFO]Finished at:ThuOct0608:12:17 MDT 2005
  32. [INFO]FinalMemory:2M/8M
  33. [INFO]----------------------------------------------------------------------------

有些事情要注意的输出:

  • 这次Maven下载更多的依赖项。这些是执行测试所必需的依赖和插件(它已经具有编译所需的依赖关系,不会再次下载)。
  • 在编译和执行测试之前,Maven编译主代码(所有这些类都是最新的,因为我们编译最后没有改变任何东西)。

如果您只想编译测试源(但不执行测试),则可以执行以下操作:

  1. mvn test-compile

    现在您可以编译应用程序源,编译测试并执行测试,您将需要继续进行下一个逻辑步骤,以便您能够...

    如何创建JAR并安装在本地仓库?

  2. 使JAR文件足够简单,可以通过执行以下命令来完成:

  1. mvnpackage

如果您查看项目的POM,您将注意到包装元素设置为jar。这是Maven从上述命令中知道生成JAR文件的方式(稍后我们将再说一下)。您现在可以查看$ {basedir} / target目录,您将看到生成的JAR文件。

现在,您需要将您生成的工件(JAR文件)安装到本地存储库中($ {user.home} /。m2 / repository是默认位置)。有关存储库的更多信息,可以参考我们的存储库介绍,但我们继续安装我们的工件!为此执行以下命令:

  1. mvn install

执行此命令后,您将看到以下输出:

  1. [INFO]----------------------------------------------------------------------------
  2. [INFO]BuildingMavenQuickStartArchetype
  3. [INFO] task-segment:[install]
  4. [INFO]----------------------------------------------------------------------------
  5. [INFO][resources:resources]
  6. [INFO][compiler:compile]
  7. Compiling1 source file to<dir>/my-app/target/classes
  8. [INFO][resources:testResources]
  9. [INFO][compiler:testCompile]
  10. Compiling1 source file to<dir>/my-app/target/test-classes
  11. [INFO][surefire:test]
  12. [INFO]Setting reports dir:<dir>/my-app/target/surefire-reports
  13.  
  14. -------------------------------------------------------
  15. T E S T S
  16. -------------------------------------------------------
  17. [surefire]Running com.mycompany.app.AppTest
  18. [surefire]Tests run:1,Failures:0,Errors:0,Time elapsed:0.001 sec
  19.  
  20. Results:
  21. [surefire]Tests run:1,Failures:0,Errors:0
  22.  
  23. [INFO][jar:jar]
  24. [INFO]Building jar:<dir>/my-app/target/my-app-1.0-SNAPSHOT.jar
  25. [INFO][install:install]
  26. [INFO]Installing<dir>/my-app/target/my-app-1.0-SNAPSHOT.jar to \
  27. <local-repository>/com/mycompany/app/my-app/1.0-SNAPSHOT/my-app-1.0-SNAPSHOT.jar
  28. [INFO]----------------------------------------------------------------------------
  29. [INFO] BUILD SUCCESSFUL
  30. [INFO]----------------------------------------------------------------------------
  31. [INFO]Total time:5 seconds
  32. [INFO]Finished at:TueOct0413:20:32 GMT-05:002005
  33. [INFO]FinalMemory:3M/8M
  34. [INFO]----------------------------------------------------------------------------
请注意,surefire插件(执行测试)会查找包含在具有特定命名约定的文件中的测试。默认情况下,测试包括:

  • **/*Test.java
  • **/Test*.java
  • **/*TestCase.java

默认排除的是:

  • **/Abstract*Test.java
  • **/Abstract*TestCase.java

您已经完成了建立,构建,测试,打包和安装典型Maven项目的过程。这可能是绝大多数项目将与Maven一起工作,如果您注意到,您所能做的一切都是由18行文件驱动,即项目模型或POM。如果您看到一个典型的Ant 构建文件,提供了我们迄今为止所实现的相同功能,您将注意到它已经是POM大小的两倍,而且我们刚刚开始!从Maven可以获得更多的功能,而不需要像现在那样添加POM。要从我们的示例Ant构建文件中获得更多的功能,您必须继续发生容易出错的添加。

那么还有什么可以免费获得的?有大量的Maven插件,即使是像上面那样简单的POM,也可以开箱即用。我们将特别提及这一个,因为它是Maven高度珍贵的功能之一:您没有任何工作,这个POM有足够的信息为您的项目生成一个网站!您最有可能要自定义您的Maven网站,但如果您按时完成所有您需要做的,以提供有关您的项目的基本信息,请执行以下命令:

  1. mvn site
还有很多其他可以执行的独立目标,例如:

  1. mvn clean

这将在启动之前删除所有构建数据的目标目录,以便它是新鲜的。

也许你想为项目生成一个IntelliJ IDEA描述符?

  1. mvn idea:idea

这可以运行在以前的IDEA项目的顶部 - 它将更新设置,而不是开始新鲜。

如果您使用的是Eclipse IDE,只需调用:

  1. mvn eclipseeclipse

注意: Maven 1.0中的一些熟悉的目标仍然存在,如jar:jar,但是它们的行为可能不如你所期望的那样。目前,jar:jar将不会重新编译源代码 - 它只是简单地从目标/ classes目录创建一个JAR ,假设已经完成了一切。

什么是SNAPSHOT版本?

注意下面显示的pom.xml文件中的版本标签的值为:-SNAPSHOT

  1. <project xmlns="http://maven.apache.org/POM/4.0.0"
  2. ...
  3. <groupId>...</groupId>
  4. <artifactId>my-app</artifactId>
  5. ...
  6. <version>1.0-SNAPSHOT</version>
  7. <name>Maven Quick Start Archetype</name>
  8. ...

SNAPSHOT 值指的是沿着一个发展分支的“最新”的代码,并且不保证该代码是稳定的或不变。相反,“release”版本中的代码(没有后缀SNAPSHOT的任何版本值)都是不变的。

换句话说,SNAPSHOT版本是最终“发布”版本之前的“开发”版本。SNAPSHOT比它的版本“老”。

 release过程中,xy-SNAPSHOT的版本更改为xy。发布过程还将开发版本增加到x。(y + 1)-SNAPSHOT。例如,版本1.0-SNAPSHOT作为版本1.0发布,新的开发版本是版本1.1-SNAPSHOT

如何使用插件?

无论何时要自定义Maven项目的构建,都可以通过添加或重新配置插件来实现。

Maven 1.0用户注意事项:在Maven 1.0中,您可以向maven.xml添加一些preGoal,并向project.properties添加一些条目。这里有点不同。

对于这个例子,我们将配置Java编译器以允许JDK 5.0源。这就像添加到您的POM一样简单:

  1. ...
  2. <build>
  3. <plugins>
  4. <plugin>
  5. <groupId>org.apache.maven.plugins</groupId>
  6. <artifactId>maven-compiler-plugin</artifactId>
  7. <version>3.3</version>
  8. <configuration>
  9. <source>1.5</source>
  10. <target>1.5</target>
  11. </configuration>
  12. </plugin>
  13. </plugins>
  14. </build>
  15. ...

你会注意到,Maven中的所有插件看起来都像一个依赖关系 - 在某些方面它们是一样的。该插件将自动下载并使用 - 包括特定版本(如果您要求它)(默认是使用最新的)。

configuration 要素适用于给定参数,从编译器插件每一个目标。在上述情况下,编译器插件已经被用作构建过程的一部分,这只是改变了配置。还可以为流程添加新目标,并配置特定目标。有关信息,请参阅构建生命周期简介。

要了解什么配置可用于插件,您可以看到插件列表,并导航到您正在使用的插件和目标。有关如何配置插件的可用参数的一般信息,请参阅“配置插件指南”。

如何为我们的JAR添加资源?

可以满足的另一个常见用例是,不需要更改我们上面提到的POM,就是在JAR文件中打包资源。对于这个常见任务,Maven再次依赖于标准目录布局,这意味着通过使用标准的Maven约定,您可以通过将这些资源放在标准目录结构中来封装JAR中的资源。

您在下面的示例中看到,我们添加了目录$ {basedir} / src / main / resources,我们将我们希望在JAR中打包的任何资源放入其中。Maven使用的简单规则是:$ {basedir} / src / main / resources目录中放置的任何目录或文件都以JAR的基础从相同的结构打包到JAR中。

  1. my-app
  2. |-- pom.xml
  3. `-- src
  4. |-- main
  5. | |-- java
  6. | | `-- com
  7. ||`-- mycompany
  8. | | `-- app
  9. ||`-- App.java
  10. | `-- resources
  11. |`-- META-INF
  12. | `-- application.properties
  13. `-- test
  14. `-- java
  15. `-- com
  16. `-- mycompany
  17. `-- app
  18. `--AppTest.java
所以你可以在我们的例子中看到,我们有一个META-INF目录,该目录下有一个application.properties文件。如果您解压缩Maven为您创建的JAR,并查看它,您将看到以下内容:

  1. |-- META-INF
  2. ||-- MANIFEST.MF
  3. ||-- application.properties
  4. |`-- maven
  5. | `-- com.mycompany.app
  6. |`-- my-app
  7. | |-- pom.properties
  8. | `-- pom.xml
  9. `-- com
  10. `-- mycompany
  11. `-- app
  12. `--App.class
您可以看到,$ {basedir} / src / main / resources的内容可以从JAR的基础开始,我们的application.properties文件位于META-INF目录中。您还会注意到像META-INF / MANIFEST.MF以及pom.xmlpom.properties文件一样的其他文件。这些标准是在Maven中生成JAR。如果您选择,您可以创建自己的清单,但如果没有,Maven将默认生成一个清单。(您也可以修改默认清单中的条目,稍后我们将会介绍。)pom.xmlpom.properties文件被打包在JAR中,使得Maven生成的每个工件都是自我描述的,并且还允许您在需要时在您自己的应用程序中使用元数据。一个简单的用法可能是检索您的应用程序的版本。在POM文件上操作将需要您使用一些Maven实用程序,但可以使用标准Java API使用属性,如下所示:

  1. #Generated by Maven
  2. #Tue Oct 04 15:43:21 GMT-05:00 2005
  3. version=1.0-SNAPSHOT
  4. groupId=com.mycompany.app
  5. artifactId=my-app
要将单元测试的类路径添加资源,您将按照与向JAR添加资源的方式相同的模式,除了放置资源的目录是$ {basedir} / src / test / resources。此时,您将有一个项目目录结构,如下所示:

  1. my-app
  2. |-- pom.xml
  3. `-- src
  4. |-- main
  5. | |-- java
  6. | | `-- com
  7. ||`-- mycompany
  8. | | `-- app
  9. ||`-- App.java
  10. | `-- resources
  11. |`-- META-INF
  12. | |-- application.properties
  13. `-- test
  14. |-- java
  15. |`-- com
  16. | `-- mycompany
  17. |`-- app
  18. | `--AppTest.java
  19. `-- resources
  20. `-- test.properties
在单元测试中,您可以使用以下代码的简单代码片段来访问测试所需的资源:

  1. ...
  2.  
  3. // Retrieve resource
  4. InputStreamis= getClass().getResourceAsStream("/test.properties");
  5.  
  6. // Do something with the resource
  7.  
  8. ...

如何过滤资源文件

有时,资源文件将需要包含只能在构建时提供的值。要在Maven中完成此操作,请使用语法$ {<property name>}对包含该值的资源引用到资源文件中。该属性可以是您的pom.xml中定义的值之一,在用户的settings.xml中定义的值,外部属性文件中定义的属性或系统属性。

有Maven的过滤器资源复制时,只需设置过滤到真正在你的资源目录的pom.xml

  1. <projectxmlns="http://maven.apache.org/POM/4.0.0"
  2. xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  3. xsi:schemaLocation="http://maven.apache.org/POM/4.0.0
  4. http://maven.apache.org/xsd/maven-4.0.0.xsd">
  5. <modelVersion>4.0.0</modelVersion>
  6.  
  7. <groupId>com.mycompany.app</groupId>
  8. <artifactId>my-app</artifactId>
  9. <version>1.0-SNAPSHOT</version>
  10. <packaging>jar</packaging>
  11.  
  12. <name>Maven Quick Start Archetype</name>
  13. <url>http://maven.apache.org</url>
  14.  
  15. <dependencies>
  16. <dependency>
  17. <groupId>junit</groupId>
  18. <artifactId>junit</artifactId>
  19. <version>4.11</version>
  20. <scope>test</scope>
  21. </dependency>
  22. </dependencies>
  23.  
  24. <build>
  25. <resources>
  26. <resource>
  27. <directory>src/main/resources</directory>
  28. <filtering>true</filtering>
  29. </resource>
  30. </resources>
  31. </build>
  32. </project>

您会注意到,我们必须添加之前不存在的buildresourcesresource 元素。此外,我们必须明确指出资源位于src / main / resources目录中。所有这些信息都是作为默认值提供的,但由于过滤的默认值为false,所以我们必须将其添加到我们的pom.xml中,以覆盖该默认值并将filtering 设置为true。

要引用在pom.xml中定义的属性,属性名称使用定义值的XML元素的名称,“pom”被允许作为项目(root)元素的别名。所以$ {project.name}指的是项目的名称,$ {project.version}是指项目的版本,$ {project.build.finalName}是指在构建项目时创建的文件的最终名称打包等。请注意,POM的某些元素具有默认值,因此不需要在pom.xml中显式定义值,以便在此处可用。类似地,可以使用以“settings”开头的属性名称来引用用户的settings.xml中的值(例如,$ {settings.localRepository}是指用户本地存储库的路径)。

为了继续我们的例子,我们将一些属性添加到application.properties文件(我们放在src / main / resources目录中),当资源被过滤时,它们的值将被提供:

  1. # application.properties
  2. application.name=${project.name}
  3. application.version=${project.version}
有了这一点,您可以执行以下命令(process-resources是构建生命周期阶段,资源被复制和过滤):

  1. mvn process-resources
并且target/classes 下的application.properties文件(最终将进入该jar)看起来像这样:

  1. # application.properties
  2. application.name=MavenQuickStartArchetype
  3. application.version=1.0-SNAPSHOT
要引用外部文件中定义的属性,您需要做的是在pom.xml中添加对该外部文件的引用。首先,我们创建我们的外部属性文件,并将其称为src / main / filters / filter.properties

  1. # filter.properties
  2. my.filter.value=hello!
接下来,我们将在pom.xml中添加对这个新文件的引用:

  1. <projectxmlns="http://maven.apache.org/POM/4.0.0"
  2. xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  3. xsi:schemaLocation="http://maven.apache.org/POM/4.0.0
  4. http://maven.apache.org/xsd/maven-4.0.0.xsd">
  5. <modelVersion>4.0.0</modelVersion>
  6.  
  7. <groupId>com.mycompany.app</groupId>
  8. <artifactId>my-app</artifactId>
  9. <version>1.0-SNAPSHOT</version>
  10. <packaging>jar</packaging>
  11.  
  12. <name>Maven Quick Start Archetype</name>
  13. <url>http://maven.apache.org</url>
  14.  
  15. <dependencies>
  16. <dependency>
  17. <groupId>junit</groupId>
  18. <artifactId>junit</artifactId>
  19. <version>4.11</version>
  20. <scope>test</scope>
  21. </dependency>
  22. </dependencies>
  23.  
  24. <build>
  25. <filters>
  26. <filter>src/main/filters/filter.properties</filter>
  27. </filters>
  28. <resources>
  29. <resource>
  30. <directory>src/main/resources</directory>
  31. <filtering>true</filtering>
  32. </resource>
  33. </resources>
  34. </build>
  35. </project>

然后,如果我们在application.properties文件中添加对此属性的引用:

  1. # application.properties
  2. application.name=${project.name}
  3. application.version=${project.version}
  4. message=${my.filter.value}
mvn process-resources命令的下一个执行将把我们的新属性值放入application.properties中。作为在外部文件中定义my.filter.value属性的替代方法,您还可以在pom.xml属性部分中定义它,您将获得相同的效果(请注意,我不需要引用src / main / filters / filter.properties):

  1. <projectxmlns="http://maven.apache.org/POM/4.0.0"
  2. xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  3. xsi:schemaLocation="http://maven.apache.org/POM/4.0.0
  4. http://maven.apache.org/xsd/maven-4.0.0.xsd">
  5. <modelVersion>4.0.0</modelVersion>
  6.  
  7. <groupId>com.mycompany.app</groupId>
  8. <artifactId>my-app</artifactId>
  9. <version>1.0-SNAPSHOT</version>
  10. <packaging>jar</packaging>
  11.  
  12. <name>Maven Quick Start Archetype</name>
  13. <url>http://maven.apache.org</url>
  14.  
  15. <dependencies>
  16. <dependency>
  17. <groupId>junit</groupId>
  18. <artifactId>junit</artifactId>
  19. <version>4.11</version>
  20. <scope>test</scope>
  21. </dependency>
  22. </dependencies>
  23.  
  24. <build>
  25. <resources>
  26. <resource>
  27. <directory>src/main/resources</directory>
  28. <filtering>true</filtering>
  29. </resource>
  30. </resources>
  31. </build>
  32.  
  33. <properties>
  34. <my.filter.value>hello</my.filter.value>
  35. </properties>
  36. </project>
过滤资源也可以从系统属性获取值; 内置于Java(如java.versionuser.home)中的系统属性或使用标准Java -D参数在命令行中定义的属性。要继续这个例子,我们来更改我们的application.properties文件,如下所示:

  1. # application.properties
  2. java.version=${java.version}
  3. command.line.prop=${command.line.prop}

现在,当您执行以下命令(请注意命令行上的command.line.prop属性的定义)时,application.properties文件将包含系统属性中的值。

  1. mvn process-resources"-Dcommand.line.prop=hello again"

如何使用外部依赖关系?

您可能已经注意到我们已经使用的POM中的依赖关系元素作为示例。事实上,你一直在使用一个外部的依赖关系,但是我们将在这里详细介绍一下这个工作原理。有关更全面的介绍,请参阅我们的依赖机制介绍。

pom.xml 的依赖关系部分列出了我们的项目需要构建的所有外部依赖项(无论是在编译时,测试时间,运行时间还是其他任务需要依赖)。现在,我们的项目仅仅依赖于JUnit(为了清楚起见,我取出了所有的资源过滤功能):

  1. <projectxmlns="http://maven.apache.org/POM/4.0.0"
  2. xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  3. xsi:schemaLocation="http://maven.apache.org/POM/4.0.0
  4. http://maven.apache.org/xsd/maven-4.0.0.xsd">
  5. <modelVersion>4.0.0</modelVersion>
  6.  
  7. <groupId>com.mycompany.app</groupId>
  8. <artifactId>my-app</artifactId>
  9. <version>1.0-SNAPSHOT</version>
  10. <packaging>jar</packaging>
  11.  
  12. <name>Maven Quick Start Archetype</name>
  13. <url>http://maven.apache.org</url>
  14.  
  15. <dependencies>
  16. <dependency>
  17. <groupId>junit</groupId>
  18. <artifactId>junit</artifactId>
  19. <version>4.11</version>
  20. <scope>test</scope>
  21. </dependency>
  22. </dependencies>
  23. </project>

对于每个外部依赖关系,您需要定义至少4项:groupId,artifactId,version和scope。groupId,artifactId和version与构建该依赖关系的项目的pom.xml中给出的相同。范围元素指示您的项目如何使用该依赖项,并且可以是(编译测试运行时 compiletest, and runtime。有关可以为依赖项指定的所有内容的更多信息,请参阅“ 项目描述符参考”。

有关依赖机制的更多信息,请参阅依赖关系机制简介。

通过有关依赖关系的信息,Maven将在构建项目时引用依赖关系。Maven在哪里引用依赖关系?Maven在您的本地存储库($ {user.home} /。m2 / repository是默认位置)中查找所有依赖项。在上一节中,我们将项目(my-app-1.0-SNAPSHOT.jar)中的工件安装到本地存储库中。一旦它被安装在那里,另一个项目可以通过将依赖关系信息添加到它的pom.xml来引用该jar作为依赖:

  1. <projectxmlns="http://maven.apache.org/POM/4.0.0"
  2. xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  3. xsi:schemaLocation="http://maven.apache.org/POM/4.0.0
  4. http://maven.apache.org/xsd/maven-4.0.0.xsd">
  5. <groupId>com.mycompany.app</groupId>
  6. <artifactId>my-other-app</artifactId>
  7. ...
  8. <dependencies>
  9. ...
  10. <dependency>
  11. <groupId>com.mycompany.app</groupId>
  12. <artifactId>my-app</artifactId>
  13. <version>1.0-SNAPSHOT</version>
  14. <scope>compile</scope>
  15. </dependency>
  16. </dependencies>
  17. </project>

在别的地方建立依赖关系呢?他们如何进入我的本地存储库?每当项目引用本地存储库中不可用的依赖项时,Maven将从远程存储库下载依赖关系到本地存储库。您可能注意到Maven下载了很多东西,当您构建了您的第一个项目(这些下载是用于构建项目的各种插件的依赖关系)。默认情况下,可以在http://repo.maven.apache.org/maven2/找到(并浏览)远程存储库Maven 。您还可以设置自己的远程存储库(可能是您的公司的中央存储库),而不是默认的远程存储库或除了默认的远程存储库。有关存储库的更多信息,可参考存储库简介。

我们为我们的项目添加另一个依赖。假设我们在代码中添加了一些日志记录,需要添加log4j作为依赖关系。首先,我们需要知道log4j的groupId,artifactId和version是什么。我们可以浏览ibiblio并寻找它,或者通过搜索“site:www.ibiblio.org maven2 log4j”来帮助Google。搜索显示一个名为/ maven2 / log4j / log4j(或/ pub / packages / maven2 / log4j / log4j)的目录。该目录是一个名为maven-metadata.xml的文件。以下是log4j的maven-metadata.xml的内容:


  1. <metadata>
  2. <groupId>log4j</groupId>
  3. <artifactId>log4j</artifactId>
  4. <version>1.1.3</version>
  5. <versioning>
  6. <versions>
  7. <version>1.1.3</version>
  8. <version>1.2.4</version>
  9. <version>1.2.5</version>
  10. <version>1.2.6</version>
  11. <version>1.2.7</version>
  12. <version>1.2.8</version>
  13. <version>1.2.11</version>
  14. <version>1.2.9</version>
  15. <version>1.2.12</version>
  16. </versions>
  17. </versioning>
  18. </metadata>

从这个文件中我们可以看到我们想要的groupId是“log4j”,而artifactId是“log4j”。我们看到很多不同的版本值可供选择; 现在,我们将使用最新版本1.2.12(一些maven-metadata.xml文件也可以指定当前版本的版本)。除了maven-metadata.xml文件,我们可以看到与每个版本的log4j库相对应的目录。在这些内部,我们将找到实际的jar文件(例如log4j-1.2.12.jar)以及一个pom文件(这是依赖关系的pom.xml,表明它可能有其他依赖关系和其他信息)和另一个maven-metadata.xml文件。还有一个与这些文件对应的md5文件,其中包含这些文件的MD5哈希值。

现在我们知道我们需要的信息,我们可以添加依赖关系到我们的pom.xml:

  1. <projectxmlns="http://maven.apache.org/POM/4.0.0"
  2. xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  3. xsi:schemaLocation="http://maven.apache.org/POM/4.0.0
  4. http://maven.apache.org/xsd/maven-4.0.0.xsd">
  5. <modelVersion>4.0.0</modelVersion>
  6.  
  7. <groupId>com.mycompany.app</groupId>
  8. <artifactId>my-app</artifactId>
  9. <version>1.0-SNAPSHOT</version>
  10. <packaging>jar</packaging>
  11.  
  12. <name>Maven Quick Start Archetype</name>
  13. <url>http://maven.apache.org</url>
  14.  
  15. <dependencies>
  16. <dependency>
  17. <groupId>junit</groupId>
  18. <artifactId>junit</artifactId>
  19. <version>4.11</version>
  20. <scope>test</scope>
  21. </dependency>
  22. <dependency>
  23. <groupId>log4j</groupId>
  24. <artifactId>log4j</artifactId>
  25. <version>1.2.12</version>
  26. <scope>compile</scope>
  27. </dependency>
  28. </dependencies>
  29. </project>
现在,当我们编译项目(mvn compile)时,我们将看到Maven为我们下载log4j依赖关系。


在远程存储库部署jar?

要将jar部署到外部存储库,必须将pom.xml中的存储库url和connectiong的认证信息配置到settings.xml中的存储库。

以下是使用scp和username / password认证的示例:

  1. <projectxmlns="http://maven.apache.org/POM/4.0.0"
  2. xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  3. xsi:schemaLocation="http://maven.apache.org/POM/4.0.0
  4. http://maven.apache.org/xsd/maven-4.0.0.xsd">
  5. <modelVersion>4.0.0</modelVersion>
  6.  
  7. <groupId>com.mycompany.app</groupId>
  8. <artifactId>my-app</artifactId>
  9. <version>1.0-SNAPSHOT</version>
  10. <packaging>jar</packaging>
  11.  
  12. <name>Maven Quick Start Archetype</name>
  13. <url>http://maven.apache.org</url>
  14.  
  15. <dependencies>
  16. <dependency>
  17. <groupId>junit</groupId>
  18. <artifactId>junit</artifactId>
  19. <version>4.11</version>
  20. <scope>test</scope>
  21. </dependency>
  22. <dependency>
  23. <groupId>org.apache.codehaus.plexus</groupId>
  24. <artifactId>plexus-utils</artifactId>
  25. <version>1.0.4</version>
  26. </dependency>
  27. </dependencies>
  28.  
  29. <build>
  30. <filters>
  31. <filter>src/main/filters/filters.properties</filter>
  32. </filters>
  33. <resources>
  34. <resource>
  35. <directory>src/main/resources</directory>
  36. <filtering>true</filtering>
  37. </resource>
  38. </resources>
  39. </build>
  40. <!--
  41. |
  42. |
  43. |
  44. -->
  45. <distributionManagement>
  46. <repository>
  47. <id>mycompany-repository</id>
  48. <name>MyCompany Repository</name>
  49. <url>scp://repository.mycompany.com/repository/maven2</url>
  50. </repository>
  51. </distributionManagement>
  52. </project>


  1. <settingsxmlns="http://maven.apache.org/SETTINGS/1.0.0"
  2. xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  3. xsi:schemaLocation="http://maven.apache.org/SETTINGS/1.0.0
  4. http://maven.apache.org/xsd/settings-1.0.0.xsd">
  5. ...
  6. <servers>
  7. <server>
  8. <id>mycompany-repository</id>
  9. <username>jvanzyl</username>
  10. <!-- Default value is ~/.ssh/id_dsa -->
  11. <privateKey>/path/to/identity</privateKey> (default is ~/.ssh/id_dsa)
  12. <passphrase>my_key_passphrase</passphrase>
  13. </server>
  14. </servers>
  15. ...
  16. </settings>

请注意,如果要连接到sshd_confing中将“PasswordAuthentication”参数设置为“否”的openssh ssh服务器,则每次用户名/密码认证时都必须键入密码(尽管您可以使用其他ssh登录客户端输入用户名和密码)。在这种情况下,您可能需要切换到公钥认证。

settings.xml中使用密码应该小心。有关详细信息,请参阅密码加密。

如何创建文档?

为了让您从Maven的文档系统开始,您可以使用原型机制来使用以下命令为现有项目生成一个站点:

  1. mvn archetype:generate \
  2. -DarchetypeGroupId=org.apache.maven.archetypes \
  3. -DarchetypeArtifactId=maven-archetype-site \
  4. -DgroupId=com.mycompany.app \
  5. -DartifactId=my-app-site

现在转到“创建网站指南”,了解如何为项目创建文档。

如何建立其他类型项目?

请注意,这些都必须在一行上。这将创建一个名为my-webapp的目录,其中包含以下项目描述符:

  1. <projectxmlns="http://maven.apache.org/POM/4.0.0"
  2. xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  3. xsi:schemaLocation="http://maven.apache.org/POM/4.0.0
  4. http://maven.apache.org/xsd/maven-4.0.0.xsd">
  5. <modelVersion>4.0.0</modelVersion>
  6.  
  7. <groupId>com.mycompany.app</groupId>
  8. <artifactId>my-webapp</artifactId>
  9. <version>1.0-SNAPSHOT</version>
  10. <packaging>war</packaging>
  11.  
  12. <dependencies>
  13. <dependency>
  14. <groupId>junit</groupId>
  15. <artifactId>junit</artifactId>
  16. <version>4.11</version>
  17. <scope>test</scope>
  18. </dependency>
  19. </dependencies>
  20.  
  21. <build>
  22. <finalName>my-webapp</finalName>
  23. </build>
  24. </project>
注意<packaging>元素 - 这告诉Maven作为WAR构建。更改到webapp项目的目录并尝试:

  1. mvn cleanpackage
您将看到目标/ my-webapp.war已建立,并且所有正常步骤都已执行。

如何一次构建多个项目

处理多个模块的概念内置于Maven。在本节中,我们将展示如何构建上述的WAR,并在一步中包括以前的JAR。

首先,我们需要在另外两个目录中添加一个父pom.xml文件,因此应该如下所示:

  1. +- pom.xml
  2. +-my-app
  3. |+- pom.xml
  4. |+- src
  5. |+- main
  6. |+- java
  7. +-my-webapp
  8. |+- pom.xml
  9. |+- src
  10. |+- main
  11. |+- webapp
您将创建的POM文件应包含以下内容:

  1. <projectxmlns="http://maven.apache.org/POM/4.0.0"
  2. xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  3. xsi:schemaLocation="http://maven.apache.org/POM/4.0.0
  4. http://maven.apache.org/xsd/maven-4.0.0.xsd">
  5. <modelVersion>4.0.0</modelVersion>
  6.  
  7. <groupId>com.mycompany.app</groupId>
  8. <artifactId>app</artifactId>
  9. <version>1.0-SNAPSHOT</version>
  10. <packaging>pom</packaging>
  11.  
  12. <modules>
  13. <module>my-app</module>
  14. <module>my-webapp</module>
  15. </modules>
  16. </project>
我们需要从webapp对JAR的依赖,所以将其添加到my-webapp / pom.xml中

  1. ...
  2. <dependencies>
  3. <dependency>
  4. <groupId>com.mycompany.app</groupId>
  5. <artifactId>my-app</artifactId>
  6. <version>1.0-SNAPSHOT</version>
  7. </dependency>
  8. ...
  9. </dependencies>
最后,将以下<parent>元素添加到子目录中的其他pom.xml文件中:

  1. <projectxmlns="http://maven.apache.org/POM/4.0.0"
  2. xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  3. xsi:schemaLocation="http://maven.apache.org/POM/4.0.0
  4. http://maven.apache.org/xsd/maven-4.0.0.xsd">
  5. <parent>
  6. <groupId>com.mycompany.app</groupId>
  7. <artifactId>app</artifactId>
  8. <version>1.0-SNAPSHOT</version>
  9. </parent>
  10. ...

现在,尝试从顶级目录运行:

  1. mvn clean install

WAR现在已经在my-webapp / target / my-webapp.war中创建,并且包括JAR:

  1. $ jar tvfmy-webapp/target/my-webapp-1.0-SNAPSHOT.war
  2. 0FriJun2410:59:56 EST 2005 META-INF/
  3. 222FriJun2410:59:54 EST 2005 META-INF/MANIFEST.MF
  4. 0FriJun2410:59:56 EST 2005 META-INF/maven/
  5. 0FriJun2410:59:56 EST 2005 META-INF/maven/com.mycompany.app/
  6. 0FriJun2410:59:56 EST 2005 META-INF/maven/com.mycompany.app/my-webapp/
  7. 3239FriJun2410:59:56 EST 2005 META-INF/maven/com.mycompany.app/my-webapp/pom.xml
  8. 0FriJun2410:59:56 EST 2005 WEB-INF/
  9. 215FriJun2410:59:56 EST 2005 WEB-INF/web.xml
  10. 123FriJun2410:59:56 EST 2005 META-INF/maven/com.mycompany.app/my-webapp/pom.properties
  11. 52FriJun2410:59:56 EST 2005 index.jsp
  12. 0FriJun2410:59:56 EST 2005 WEB-INF/lib/
  13. 2713FriJun2410:59:56 EST 2005 WEB-INF/lib/my-app-1.0-SNAPSHOT.jar

这个怎么用?首先,父POM创建(称为app),具有pom的包装和定义的模块列表。这告诉Maven运行所有的项目集,而不是仅仅是当前的(为了覆盖这个行为,你可以使用--non-recursive命令行选项)。

接下来,我们告诉WAR它需要我的应用程序 JAR。这做了一些事情:它使它在类路径中可用于WAR中的任何代码(在这种情况下无),它确保JAR始终在WAR之前构建,并且它向WAR插件指示将JAR包括在其库目录。

你可能已经注意到,junit-4.11.jar是一个依赖关系,但并没有在WAR中结束。其原因是<scope> test </ scope>元素 - 它只需要进行测试,因此编译时依赖关系my-app不包含在Web应用程序中。

最后一步是包括父定义。这与您可能从Maven 1.0熟悉的扩展元素不同:这确保了即使项目通过在存储库中查找而与其父级分开分发,也可以始终找到POM。

与Maven 1.0不同,不需要运行install (安装来成功执行这些步骤 - 您可以自行运行package (软件包),并且将从目标目录而不是本地存储库中使用反应器中的工件。

您可能希望从顶级目录再次生成您的IDEA工作区

  1. mvn idea:idea


原创粉丝点击