Apache Maven 入门篇 ( 下 )

 

Apache Maven 入门篇 ( )

 

第一篇文章 大概的介绍了一下 Apache Maven 以及它的下载和安装,并且运行了一个简单的示例。那么在对 maven 有了一点接触后,接下去的一步是要了解 maven 的核心概念,这样才能在使用 maven 的时候游刃有余。

 

接下来我们介绍下面这几个核心概念:

  • POM (Project Object Model)

  • Maven 插件

  • Maven 生命周期

  • Maven 依赖管理

  • Maven

POM (Project Object Model)

 

一个项目所有的配置都放置在 POM 文件中:定义项目的类型、名字,管理依赖关系,定制插件的行为等等。比如说 ,你可以配置 compiler 插件让它使用 java 1.5 来编译。

 

现在看一下 第一篇文章 中示例的 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.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> 
  <modelVersion>4.0.0</modelVersion> 

  <groupId>com.mycompany.helloworld</groupId> 
  <artifactId>helloworld</artifactId> 
  <version>1.0-SNAPSHOT</version> 
  <packaging>jar</packaging> 

  <name>helloworld</name> 
  <url>http://maven.apache.org</url> 

  <properties> 
    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> 
  </properties> 

  <dependencies> 
    <dependency> 
      <groupId>junit</groupId> 
      <artifactId>junit</artifactId> 
      <version>3.8.1</version> 
      <scope>test</scope> 
    </dependency> 
  </dependencies> 
</project>
   

 

POM 中, groupId, artifactId, packaging, version 叫作 maven 坐标,它能唯一的确定一个项目。有了 maven 坐标,我们就可以用它来指定我们的项目 所依赖 的其他项目,插件,或者父项目。一般 maven 坐标写成如下的格式:

     groupId:artifactId:packaging:version

我们的例子就会写成:

     com.mycompany.helloworld : helloworld: jar: 1.0-SNAPSHOT

 

我们的 helloworld 示例很简单,但是 大项目一般会分成几个子项目 。在这种情况下, 每个子项目就会有自己的 POM 文件,然后它们会有一个共同的父项目。这样只要构建父项目就能够构建所有的子项目了。子项目的 POM 会继承父项目的 POM 另外, 所有的 POM 都继承了一个 Super-POM Super-POM 设置了一些默认值,比如在 第一篇文章 中提到的默认的目录结构,默认的插件等等,它遵循了惯例优于配置的原则。所以尽管 我们的这个 POM 很简单,但是这只是你看得见的一部分。 运行时候的 POM 要复杂的多。 如果你想看到 运行时候的 POM 全部 内容的话,可以运行下面的命令

     $ mvn help:effective-pom

 

Maven 插件

 

第一篇文章 ,我们用了 mvn archetype:generate 命令来生成一个项目。那么这里的 archetype:generate 是什么意思呢? archetype 是一个插件的名字, generate 是目标 (goal) 的名字。这个命令的意思是告诉 maven 执行 archetype 插件的 generate 目标。插件目标通常会写成 pluginId:goalId

 

一个目标是一个工作单元,而插件则是一个或者多个目标的集合。比如说 Jar 插件, Compiler 插件, Surefire 插件等。从看名字就能知道, Jar 插件包含建立 Jar 文件的目标, Compiler 插件包含编译源代码和单元测试代码的目标。 Surefire 插件的话,则是运行单元测试。

 

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

 

Maven 生命周期

 

上一篇文章 中,我们用的第二个命令是: mvn package 。这里的 package 是一个 maven 的生命周期阶段 (lifecycle phase ) 。生命周期指项目的构建过程,它包含了一系列的有序的阶段 (phase) ,而一个阶段就是构建过程中的一个步骤。

 

那么生命周期阶段和上面说的插件目标之间是什么关系呢?插件目标可以绑定到生命周期阶段上。一个生命周期阶段可以绑定多个插件目标。当 maven 在构建过程中逐步的通过每个阶段时,会执行该阶段所有的插件目标。

 

maven 能支持不同的生命周期,但是最常用的是默认的 Maven 生命周期 (default Maven lifecycle ) 。如果你没有对它进行任何的插件配置或者定制的话,那么上面的命令 mvn package 会依次执行默认生命周期中直到包括 package 阶段前的所有阶段的插件目标:

  1. process-resources 阶段: resources:resources

  2. compile 阶段: compiler:compile

  3. process-classes 阶段: ( 默认无目标 )

  4. process-test-resources 阶段: resources:testResources

  5. test-compile 阶段: compiler:testCompile

  6. test 阶段: surefire:test

  7. prepare-package 阶段: ( 默认无目标 )

  8. package 阶段: jar:jar

 

Maven 依赖管理

 

之前我们说过, maven 坐标能够确定一个项目。换句话说,我们可以用它来解决依赖关系。在 POM 中,依赖关系是在 dependencies 部分中定义的。在上面的 POM 例子中, 我们用 dependencies 定义了对于 junit 的依赖:

 

  <dependencies> 
    <dependency> 
      <groupId>junit</groupId> 
      <artifactId>junit</artifactId> 
      <version>3.8.1</version> 
      <scope>test</scope> 
    </dependency> 
  </dependencies> 

 

 

 

那这个例子很简单,但是实际开发中我们会有复杂得多的依赖关系,因为被依赖的 jar 文件会有自己的依赖关系。那么我们是不是需要把那些间接依赖的 jar 文件也都定义在 POM 中呢?答案是不需要,因为 maven 提供了传递依赖的特性。

 

所谓传递依赖是指 maven 会检查被依赖的 jar 文件,把它的依赖关系纳入最终解决的依赖关系链中。针对上面的 junit 依赖关系,如果你看一下 maven 的本地库(我们马上会解释 maven 库) ~/.m2/repository/junit/junit/3.8.1/

 


 

你会发现 maven 不但下载了 junit-3.8.1.jar ,还下载了它的 POM 文件。这样 maven 就能检查 junit 的依赖关系,把它所需要的依赖也包括进来。

 

POM dependencies 部分中, scope 决定了依赖关系的适用范围。我们的例子中 junit scope test ,那么它只会在执行 compiler:testCompile and surefire:test 目标的时候才会被加到 classpath 中,在执行 compiler:compile 目标时是拿不到 junit 的。

 

我们还可以指定 scope provided ,意思是 JDK 或者容器会提供所需的 jar 文件。比如说在做 web 应用开发的时候,我们在编译的时候需要 servlet API jar 文件,但是在打包的时候不需要把这个 jar 文件打在 WAR 中,因为 servlet 容器或者应用服务器会提供的。

 

scope 的默认值是 compile ,即任何时候都会被包含在 classpath 中,在打包的时候也会被包括进去。

 

Maven

 

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

 

但是不是所有的 jar 文件都是可以从默认的远程库下载的,比如说我们自己开发的项目。这个时候,有两个选择:要么在公司内部设置定制库,要么手动下载和安装所需的 jar 文件到本地库。

 

本地库是指 maven 下载了插件或者 jar 文件后存放在本地机器上的拷贝。在 Linux p { margin-bottom: 0.08in; }

上,它的位置在 ~/.m2/repository ,在 Windows XP 上,在 C:\Documents and Settings\username\.m2\repository ,在 Windows 7 上,在 C:\Users\username\.m2\repository 。当 maven 查找需要的 jar 文件时,它会先在本地库中寻找,只有在找不到的情况下,才会去远程库中找。

 

运行下面的命令能把我们的 helloworld 项目安装到本地库:

     $mvn install

 

一旦一个项目被安装到了本地库后,你别的项目就可以通过 maven 坐标和这个项目建立依赖关系。比如如果我现在有一个新项目需要用到 helloworld ,那么在运行了上面的 mvn install 命令后,我就可以如下所示来建立依赖关系:

 

<dependency>
  <groupId>com.mycompany.helloworld</groupId>
  <artifactId>helloworld</artifactId>
  <version>1.0-SNAPSHOT</version>
</dependency> 

 

好了, maven 的核心概念就简单的介绍到这里。至于在 Eclipse 中如何使用 maven ,这个网上很多了, google 一下就行。

 

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值