码迷,mamicode.com
首页 > 其他好文 > 详细

Maven学习

时间:2015-06-11 23:03:58      阅读:170      评论:0      收藏:0      [点我收藏+]

标签:平台

Maven简介

  • 主要用于基于Java平台的项目构建、依赖管理和项目信息管理
  • 约定优于配置(Convention Over Configuration),使项目构建标准化,消除重复及琐碎的任务,且提供中央仓库,通过坐标系统来有序地管理以来
  • 核心是POM文件

本文是对《Maven实战》的学习和总结


坐标

没有Maven的情况下,开发中需要某个依赖时,得去它的官网上寻找,依赖多了之后,就得花费大量时间寻找和下载依赖,没有统一的规范。而Maven定义了一组规则:世界上任何一个构件都可以用Maven坐标唯一标识,包括groupId、artifactId、version。packaging、classifier。Maven提供一个中央仓库,包含了世界上大部分流行的开源项目构件,只要提供正确的坐标,Maven就会自动下载需要的构件。
坐标定义:

<groupId>org.sonatype.nexus</groupId>
<artifactId>nexus-indexer</artifactId>
<version>2.0.0</version>
<packaging>jar</packaging>
  • groupId定义了项目属于哪个组,通常和域名反向对应(和项目所在组织或公司相关),如googlecode的myapp项目,groupId就是com.googlecode.myapp
  • artifactId定义当前项目在组中唯一的ID,推荐用实际项目名称做前缀,即artifactId=项目名+模块名,因为生成的构件会以artifactId-version.packageing命名,假如多个项目都有core模块,就好区分了,如foo-core-1.2.jar、ba-core-1.2.jar。
  • version指定了项目当前的版本,如1.0-SNAPSHOT指快照,说明该项目还处在开发中,是不稳定的版本
  • packaging指打包方式,jar、war或pom,可选,默认是jar
  • classifier定义构件输出的一些附属构件,如主构件是nexus-indexer-2.0.0.jar,项目还使用一些插件生成附属构件,如nexus-indexer-2.0.0-javadoc.jar。不能直接定义classifier因为附属构件不是项目直接默认生成的,而是附加的插件生成的

依赖

<dependencies>
 <dependency>
  <groupId>..</groupId>
  <artifactId>..</artifactId>
  <version>..</version>
  <type>..</type>
  <scope>..</scope>
  <optional>..</optional>
  <exclusions>
   <exclusion>
   ...
   </exclusion>
  </exclusions>
 </dependency>
</dependencies>

依赖范围

Maven有三种classpath,编译、测试、运行,依赖范围就是用scope元素来控制classpath,scope的主要种类:
- compile:对三种都有效
- test:只对测试classpath有效,编译代码或运行项目时无法使用此类依赖
- provided:编译和测试有效,运行无效
- runtime:测试和运行有效,编译无效
- system:和provided范围一样,只是构件必须显式指明文件路径

传递性依赖

A依赖B,B依赖C,A对于C是传递性依赖,如果第二直接依赖范围(B-C)是compile,传递性依赖范围和第一直接依赖范围(A-B)一致,第二直接依赖范围是test,则依赖不会传递。如果B-C是可选依赖(optional元素是true)

排除依赖

用exclusion元素排除依赖


仓库

没有仓库之前,每个项目都要存放依赖,很多都是重复的,浪费磁盘空间且很难统一管理。有了坐标机制,Maven就可以在某个位置统一存储所有Maven项目共享的构件,这个位置就是仓库。任意构件都有唯一坐标,根据坐标就可以定义其在仓库中的唯一存储路径,groupId/artifactId/version/artifactId-version.packaging

仓库分类

两类:本地仓库和远程仓库,Maven找某构件时,先看本地仓库,不存在就去远程仓库下载。

  • 远程仓库:
    • 中央仓库是Maven自带的远程仓库
    • 私服是特殊的远程仓库,在局域网内部架设的私有的仓库服务器,用其代理外部的远程仓库,节省带宽和时间,且第三方项目或内部项目还能部署到私服上供其他项目使用,可以用Nexus架设私服
<repositories>
 <repository>
  <id>..</id>
  <name>..</name>
  <url>..</url>
  <releases>
   <enabled>true</enabled> <!--表示开启仓库的发布版本下载支持-->
  </releases>
  <snapshots>
   <enabled>false</enabled> <!--表示关闭仓库的快照版本下载支持-->
   <updatePolicy>daily</updatePolicy> <!--表示每天检查一次更新-->
  </snapshots>
 </repository>
</repositories>
  • 本地仓库:
    • 一般在用户目录的.m2/repository/目录

本地项目可以构建后安装到本地仓库,供其他项目使用,mvn clean install
也可以部署到远程仓库,mvn clean deploy,需要配置distributionManagement元素

<distributionManagement>
 <repository> <!--表示发布版本构件的仓库-->
  <id>..</id>
  <name>..</name>
  <url>..</url>
 </repository>
 <snapshotRepository> <!--表示快照版本构件的仓库-->
  <id>..</id>
  <name>..</name>
  <url>..</url>
 </snapshotRepository>
</distributionManagement>

快照版本

正在开发的模块版本一般都设为快照,如2.0.0-SNAPSHOT,Maven会为快照自动打上时间戳,有了时间戳,Maven就能找到仓库中该快照版本的最构件。其他项目依赖该快照时,每次构建的时候都会下载最新的构件,即使用的是别人最新的代码。快照的“最新”是基于groupId/artifactId/version/maven-metadata.xml计算出来的


生命周期 & 插件

Maven的生命周期是为了对所有的构建过程进行抽象和统一。生命周期抽象了构建的各个步骤,而具体的任务是由插件来实现。

  • Maven有三套相互独立的生命周期:clean、default和site。default是核心,定义了真正构建时执行的所有步骤,如validate、process-sources、complie、test-compile、test、package、verify、install、deploy等。
  • 插件可以有多个功能,每个功能就是一个插件目标,用插件前缀:插件目标表示
  • 生命周期的阶段和插件的目标相互绑定,用以完成具体的构建任务
  • Maven为主要的生命周期阶段绑定了很多插件的目标,用命令行调用生命周期阶段时,对于的插件目标就会执行相应的任务,如:
    • clean与maven-clean-plugin:clean绑定
    • package与maven-jar-plugin:jar绑定
    • install与maven-install-plugin:install绑定

从命令的执行信息可以看出用了哪些插件目标,执行了生命周期的哪些阶段

自定义绑定

用户自己选择将某插件目标绑定到生命周期的某个阶段

<build>
 <plugins> <!--表示发布版本构件的仓库-->
  <plugin>
   <groupId>..</groupId>
   <artifactId>..</artifactId>
   <version>..</version>
   <executions>
    <execution>
     <id>..</id>
     <phase>..</phase> <!--生命周期阶段-->
     <goals>..</goals> <!--插件目标-->
    </execution>  
   </executions> 
  <plugin>
 </plugins>
</build>

插件配置

插件目标有可配置的参数,可通过命令行和POM等方式来配置

  • 命令行配置
    • 如maven-surefire-plugin提供maven.test.skip参数,为true时跳过执行测试
    • 运行命令行时使用 mvn install -Dmaven.test.skip=truemvn isntall -DskipTests=true
  • POM配置,全局一次性配置
    • 如通常会配置maven-compiler-plugin告诉它编译Java某版本的源文件,用<configuration>元素

插件仓库

与依赖构件一样,插件构件也基于坐标存储在Maven仓库中

<pluginRepositories>
 <pluginRepository>
  <id>..</id>
  <name>..</name>
  <url>..</url>
  <releases>
   <enabled>true</enabled> <!--表示开启仓库的发布版本下载支持-->
  </releases>
  <snapshots>
   <enabled>false</enabled> <!--表示关闭仓库的快照版本下载支持-->
  </snapshots>
 </pluginRepository>
</pluginRepositories>

聚合

一次构建多个项目,对聚合模块来说,打包方式的值必须为pom,用<modules>来实现模块的聚合。

聚合模块知道有哪些被聚合的模块,但是被聚合的模块不知道这个聚合模块的存在。

继承

让子模块继承父模块,消除一些重复的配置。

父模块的<dependencyManagement>元素既能让子模块继承父模块的依赖配置,约束子模块的<dependencies>中依赖的使用,比如统一版本信息等,又能保证子模块依赖使用的灵活性,因为该元素不会让子模块引入实际的依赖,除非子模块声明了依赖的使用,这样就不会发生多个子模块使用依赖版本不一致的情况。

同理,<pluginManagement>也能帮助管理插件,但不会给子模块造成实际的插件调用行为,除非子模块的POM中配置了真正的plugin元素(grouppId和artifactId跟父模块的一致)

继承关系的父POM不知道有哪些子模块继承了它,但子模块都必须知道自己的父POM是什么。


反应堆

对多模块项目,反应堆包含了模块之间继承与依赖的关系,从而能够自动计算出合理的模块构建顺序

Maven学习

标签:平台

原文地址:http://blog.csdn.net/allhaillouis/article/details/46459309

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!