Maven学习笔记(二)

2. maven概要

首先我把maven的概念快速的梳理一下,让我们快速地建立起一个比较精确的maven应用场景。
2.1 maven不是什么

读书时候要先限定范围,避免一些有害的遐想。要说maven不是什么,我们可以从如下几个要点来展开

maven不是ant,也不是make。 
    我们以前接触的构建工具,需要写一些详细的步骤,比如: compile project1/src/*.java 等类似的语句。这些语句正是我们使用ant和make所要编写的东西。maven采用了"约定优于配置"的方法,一些开发常用的操作和步骤已经固化在 maven中,所以使用者不再需要去编写那些烦人的语句了。同时,maven内置了开发流程的支持,它不仅能够编译,同样能够打包、发布,也能够一气呵成做完这些所有的步骤。
    maven不是ivy 
    依赖管理是maven的功能之一,虽然很多人包括我以前都是只用它的依赖管理功能,但是要深入运用的话,我们就可以看到更多的内容。更重要的是,maven在依赖关系中加入了scope的概念,进一步细化了依赖关系的划分。

2.2 maven是什么

maven将自己定位为一个项目管理工具。它负责管理项目开发过程中的几乎所有的东西:

版本 
    maven有自己的版本定义和规则
    构建 
    maven支持许多种的应用程序类型,对于每一种支持的应用程序类型都定义好了一组构建规则和工具集。
    输出物管理 
    maven可以管理项目构建的产物,并将其加入到用户库中。这个功能可以用于项目组和其他部门之间的交付行为。
    依赖关系 
    maven对依赖关系的特性进行细致的分析和划分,避免开发过程中的依赖混乱和相互污染行为
    文档和构建结果 
    maven的site命令支持各种文档信息的发布,包括构建过程的各种输出,javadoc,产品文档等。
    项目关系 
    一个大型的项目通常有几个小项目或者模块组成,用maven可以很方便地管理
    移植性管理 
    maven可以针对不同的开发场景,输出不同种类的输出结果。

2.3 maven的生命周期

maven把项目的构建划分为不同的生命周期(lifecycle),在我看来,划分的已经是非常仔细了,大家可以参考这里。粗略一点的话,它这个过程(phase)包括:编译、测试、打包、集成测试、验证、部署。maven中所有的执行动作(goal)都需要指明自己在这个过程中的执行位置,然后maven执行的时候,就依照过程的发展依次调用这些goal进行各种处理。

这个也是maven的一个基本调度机制。一般来说,位置稍后的过程都会依赖于之前的过程。当然,maven同样提供了配置文件,可以依照用户要求,跳过某些阶段。
2.4 maven的"约定优于配置"

所谓的"约定优于配置",在maven中并不是完全不可以修改的,他们只是一些配置的默认值而已。但是使用者除非必要,并不需要去修改那些约定内容。maven默认的文件存放结构如下:

/项目目录
        pom.xml 用于maven的配置文件
        /src 源代码目录
            /src/main 工程源代码目录
                /src/main/java 工程java源代码目录
            /src/main/resource 工程的资源目录
            /src/test 单元测试目录
                /src/test/java
        /target 输出目录,所有的输出物都存放在这个目录下
            /target/classes 编译之后的class文件

每一个阶段的任务都知道怎么正确完成自己的工作,比如compile任务就知道从src/main/java下编译所有的java文件,并把它的输出class文件存放到target/classes中。

对maven来说,采用"约定优于配置"的策略可以减少修改配置的工作量,也可以降低学习成本,更重要的是,给项目引入了统一的规范。
2.5 maven的版本规范

maven使用如下几个要素来唯一定位某一个输出物: groupId:artifactId:packaging:version 。比如org.springframework:spring:2.5 。每个部分的解释如下:

groupId 
    团体,公司,小组,组织,项目,或者其它团体。团体标识的约定是,它以创建这个项目的组织名称的逆向域名(reverse domain name)开头。来自Sonatype的项目有一个以com.sonatype开头的groupId,而Apache Software的项目有以org.apache开头的groupId。
    artifactId 
    在groupId下的表示一个单独项目的唯一标识符。比如我们的tomcat, commons等。不要在artifactId中包含点号(.)。
    version 
    一个项目的特定版本。发布的项目有一个固定的版本标识来指向该项目的某一个特定的版本。而正在开发中的项目可以用一个特殊的标识,这种标识给版本加上一个"SNAPSHOT"的标记。 
    虽然项目的打包格式也是Maven坐标的重要组成部分,但是它不是项目唯一标识符的一个部分。一个项目的 groupId:artifactId:version使之成为一个独一无二的项目;你不能同时有一个拥有同样的groupId, artifactId和version标识的项目。
    packaging 
    项目的类型,默认是jar,描述了项目打包后的输出。类型为jar的项目产生一个JAR文件,类型为war的项目产生一个web应用。
    classifier 
    很少使用的坐标,一般都可以忽略classifiers。如果你要发布同样的代码,但是由于技术原因需要生成两个单独的构件,你就要使用一个分类器(classifier)。例如,如果你想要构建两个单独的构件成JAR,一个使用Java 1.4编译器,另一个使用Java 6编译器,你就可以使用分类器来生成两个单独的JAR构件,它们有同样的groupId:artifactId:version组合。如果你的项目使用本地扩展类库,你可以使用分类器为每一个目标平台生成一个构件。分类器常用于打包构件的源码,JavaDoc或者二进制集合。

maven有自己的版本规范,一般是如下定义 <major version>.<minor version>.<incremental version>-<qualifier> ,比如1.2.3-beta-01。要说明的是,maven自己判断版本的算法是major,minor,incremental部分用数字比较,qualifier部分用字符串比较,所以要小心 alpha-2和alpha-15的比较关系,最好用 alpha-02的格式。

maven在版本管理时候可以使用几个特殊的字符串 SNAPSHOT ,LATEST ,RELEASE 。比如"1.0-SNAPSHOT"。各个部分的含义和处理逻辑如下说明:

SNAPSHOT 
    如果一个版本包含字符串"SNAPSHOT",Maven就会在安装或发布这个组件的时候将该符号展开为一个日期和时间值,转换为UTC时间。例如,"1.0-SNAPSHOT"会在2010年5月5日下午2点10分发布时候变成1.0-20100505-141000-1。 
    这个词只能用于开发过程中,因为一般来说,项目组都会频繁发布一些版本,最后实际发布的时候,会在这些snapshot版本中寻找一个稳定的,用于正式发布,比如1.4版本发布之前,就会有一系列的1.4-SNAPSHOT,而实际发布的1.4,也是从中拿出来的一个稳定版。
    LATEST 
    指某个特定构件的最新发布,这个发布可能是一个发布版,也可能是一个snapshot版,具体看哪个时间最后。
    RELEASE 
    指最后一个发布版。

2.6 maven的组成部分

maven把整个maven管理的项目分为几个部分,一个部分是源代码,包括源代码本身、相关的各种资源,一个部分则是单元测试用例,另外一部分则是各种maven的插件。对于这几个部分,maven可以独立管理他们,包括各种外部依赖关系。
2.7 maven的依赖管理

依赖管理一般是最吸引人使用maven的功能特性了,这个特性让开发者只需要关注代码的直接依赖,比如我们用了spring,就加入spring依赖说明就可以了,至于spring自己还依赖哪些外部的东西,maven帮我们搞定。

任意一个外部依赖说明包含如下几个要素:groupId, artifactId, version, scope, type, optional。其中前3个是必须的,各自含义如下:

groupId 必须
    artifactId 必须
    version 必须。 
    这里的version可以用区间表达式来表示,比如(2.0,)表示>2.0,[2.0,3.0)表示2.0<=ver<3.0;多个条件之间用逗号分隔,比如[1,3),[5,7]。
    scope 作用域限制
    type 一般在pom引用依赖时候出现,其他时候不用
    optional 是否可选依赖

maven认为,程序对外部的依赖会随着程序的所处阶段和应用场景而变化,所以maven中的依赖关系有作用域(scope)的限制。在maven中,scope包含如下的取值:

compile(编译范围) 
    compile是默认的范围;如果没有提供一个范围,那该依赖的范围就是编译范围。编译范围依赖在所有的classpath中可用,同时它们也会被打包。
    provided(已提供范围) 
    provided依赖只有在当JDK或者一个容器已提供该依赖之后才使用。例如,如果你开发了一个web应用,你可能在编译classpath中需要可用的Servlet API来编译一个servlet,但是你不会想要在打包好的WAR中包含这个Servlet API;这个Servlet API JAR由你的应用服务器或者servlet容器提供。已提供范围的依赖在编译classpath(不是运行时)可用。它们不是传递性的,也不会被打包。
    runtime(运行时范围) 
    runtime依赖在运行和测试系统的时候需要,但在编译的时候不需要。比如,你可能在编译的时候只需要JDBC API JAR,而只有在运行的时候才需要JDBC驱动实现。
    test(测试范围) 
    test范围依赖 在一般的 编译和运行时都不需要,它们只有在测试编译和测试运行阶段可用。测试范围依赖在之前的???中介绍过。
    system(系统范围) 
    system范围依赖与provided类似,但是你必须显式的提供一个对于本地系统中JAR文件的路径。这么做是为了允许基于本地对象编译,而这些对象是系统类库的一部分。这样的构件应该是一直可用的,Maven也不会在仓库中去寻找它。 如果你将一个依赖范围设置成系统范围,你必须同时提供一个systemPath元素 。注意该范围是不推荐使用的(你应该一直尽量去从公共或定制的Maven仓库中引用依赖)。

另外,代码有代码自己的依赖,各个maven使用的插件也可以有自己的依赖关系。依赖也可以是可选的,比如我们代码中没有任何cache依赖,但是hibernate可能要配置cache,所以该cache的依赖就是可选的。
2.8 多项目管理(近期不会用到,暂时跳过,标红标红)

maven的多项目管理也是非常强大的。一般来说,maven要求同一个工程的所有子项目都放置到同一个目录下,每一个子目录代表一个项目,比如

总项目/
        pom.xml 总项目的pom配置文件
        子项目1/
            pom.xml 子项目1的pom文件
        子项目2/
            pom.xml 子项目2的pom文件

按照这种格式存放,就是继承方式,所有具体子项目的pom.xml都会继承总项目pom的内容,取值为子项目pom内容优先。

要设置继承方式,首先要在总项目的pom中加入如下配置
<modules> 
    <module>simple-weather</module> 
    <module>simple-webapp</module> 
</modules>

其次在每个子项目中加入
<parent> 
    <groupId>org.sonatype.mavenbook.ch06</groupId> 
    <artifactId>simple-parent</artifactId> 
    <version>1.0</version> 
</parent>

即可。

当然,继承不是唯一的配置文件共用方式,maven还支持引用方式。引用pom的方式更简单,在依赖中加入一个type为pom的依赖即可。

<project> 
    <description>This is a project requiring JDBC</description> 
    ... 
    <dependencies> 
        ... 
        <dependency> 
            <groupId>org.sonatype.mavenbook</groupId> 
            <artifactId>persistence-deps</artifactId> 
            <version>1.0</version> 
            <type>pom</type> 
        </dependency> 
    </dependencies> 
</project>
        
2.9 属性

用户可以在maven中定义一些属性,然后在其他地方用${xxx}进行引用。比如:

<project> 
    <modelVersion>4.0.0</modelVersion> 
    ... 
    <properties> 
        <var1>value1</var1> 
    </properties> 
</project>
maven提供了三个隐式的变量,用来访问系统环境变量、POM信息和maven的settings:

env 
    暴露操作系统的环境变量,比如env.PATH
    project 
    暴露POM中的内容,用点号(.)的路径来引用POM元素的值,比如${project.artifactId}。另外,java的系统属性比如user.dir等,也暴露在这里。
    settings 
    暴露maven的settings的信息,也可以用点号(.)来引用。maven把系统配置文件存放在maven的安装目录中,把用户相关的配置文件存放在~/.m2/settings.xml(unix)或者%USERPROFILE%/.m2/settings.xml(windows)中。

2.10 maven的profile

profile是maven的一个重要特性,它可以让maven能够自动适应外部的环境变化,比如同一个项目,在linux下编译linux的版本,在win下编译win的版本等。一个项目可以设置多个profile,也可以在同一时间设置多个profile被激活(active)的。自动激活的 profile的条件可以是各种各样的设定条件,组合放置在activation节点中,也可以通过命令行直接指定。profile包含的其他配置内容可以覆盖掉pom定义的相应值。如果认为profile设置比较复杂,可以将所有的profiles内容移动到专门的 profiles.xml 文件中,不过记得和pom.xml放在一起。

activation节点中的激活条件中常见的有如下几个:

os 
    判断操作系统相关的参数,它包含如下可以自由组合的子节点元素
        message - 规则失败之后显示的消息
        arch - 匹配cpu结构,常见为x86
        family - 匹配操作系统家族,常见的取值为:dos,mac,netware,os/2,unix,windows,win9x,os/400等
        name - 匹配操作系统的名字
        version - 匹配的操作系统版本号
        display - 检测到操作系统之后显示的信息
    jdk 
    检查jdk版本,可以用区间表示。
    property 
    检查属性值,本节点可以包含name和value两个子节点。
    file 
    检查文件相关内容,包含两个子节点:exists和missing,用于分别检查文件存在和不存在两种情况。

原文路径:http://blog.csdn.net/houpengfei111/article/details/9142869

时间: 2024-11-04 03:47:38

Maven学习笔记(二)的相关文章

Maven学习笔记(二) :Maven的安装与配置

在Windows上安装Maven:  1.  首先检查JDK安装 通过命令行执行命令:echo %JAVA_HOME%和 java  -version,可以查看当前java的安装目录及java的版本,maven要求JDK的版本必须在1.4以上. 2. 下载Maven 前往maven的下载页面:http://maven.apache.org/download.cgi下载最新或稳定版的maven,如:apache-maven-3.2.3-bin.zip. 3. 安装Maven 将压缩文件解压到你想要

Maven学习笔记二:常用命令

Maven常用命令: 1.mvn -v:显示版本信息 2.创建Java项目 mvn archetype:generate groupid:项目标识,java包的目录结构: artifactid:项目名称 示例: mvn archetype:generate -DarchetypeCatalog=internal -Dgroupid=com.demo.app -Dartifactid=myapp -Dversion=1.0 -DarchetypeCatalog=internal:不从远程服务器上获

Maven学习笔记二(配置本地仓库)

Maven的默认本地仓库在: ${user.home}/.m2/repository; 如果需要自定义仓库路径,可以找到maven文件夹下的conf下的setting.xml文件进行修改, 以下自定义仓库路径为E:\java\Maven\apache-maven-3.3.9\conf\repository    (repository为存放jar包的文件夹) 项目规约 src/main/java -- 存放项目的.java 文件(开发源代码) src/main/resources -- 存放项目

Maven学习笔记(二):Maven仓库

Maven仓库的知识点比较少,理解起来也很简单. 仓库只有两类:本地仓库和远程仓库.所谓本地仓库就是自己机器上的仓库,在setting.xml文件中进行配置: 1 <localRepository>E:/MavenStore</localRepository> 本地仓库中存储的就是在使用Maven解析项目时从远程仓库下载的依赖和自己安装的一些构建. 远程仓库很明显就是网络上的仓库,存储在一个神秘的地方(好吧,其实我是不知道在哪里).当Maven解析项目时,如果本地没有需要的依赖,就

Maven学习笔记之——坐标和依赖(中)

Maven学习笔记之--坐标和依赖(中) 1.    传递性依赖 1.1    何为传递性依赖 项目中经常有引入一个jar包还要引入其他与其相关的jar包.自己搜的话要注意很多.比如版本问题等.而Maven会解析解析各个直接依赖的POM.将哪些必要的间接依赖以传递依赖的形式引入到项目中. 依赖范围不仅可以控制依赖与三种classpath关系.还对传递依赖产生影响. 假设A依赖B,B依赖C,我们说A对于B是第一直接依赖,B对于C是第二直接依赖,A对于C是传递性依赖.第一直接依赖的范围和第二直接依赖

Maven学习笔记之——仓库(中)

Maven学习笔记之--仓库(中) 1.    远程仓库的配置 当出现默认的中央仓库无法满足我们的需求或者连接不上的时候.我们可以通过POM文件来指定远程仓库. <repositories> <repository> <id>jboss-maven2-release-repository</id> <name>JBoss Repository</name> <url>http://repository.jboss.org/

Caliburn.Micro学习笔记(二)----Actions

Caliburn.Micro学习笔记(二)----Actions 上一篇已经简单说了一下引导类和简单的控件绑定 我的上一个例子里的button自动匹配到ViewModel事件你一定感觉很好玩吧 今天说一下它的Actions,看一下Caliburn.Micro给我们提供了多强大的支持 我们还是从做例子开始 demo的源码下载在文章的最后 例子1.无参数方法调用 点击button把textBox输入的文本弹出来 如果textbox里没有文本button不可点,看一下效果图 看一下前台代码 <Stac

Maven学习笔记

Maven学习笔记 Maven是项目管理工具 1. 安装Maven 在apache官网(http://maven.apache.org/download.cgi) 下载apache-maven-3.3.3-bin.zip和apache-maven-3.3.3-src.zip:解压,把bin的位置设在环境变量里, 新建环境变量名:MAVEN_HOME 值:C:\Users\pengtao.yue\apache-maven-3.3.3\bin 在path中加入:%MAVEN_HOME% 在DOS中输

2. 蛤蟆Python脚本学习笔记二基本命令畅玩

2. 蛤蟆Python脚本学习笔记二基本命令畅玩 本篇名言:"成功源于发现细节,没有细节就没有机遇,留心细节意味着创造机遇.一件司空见惯的小事或许就可能是打开机遇宝库的钥匙!" 下班回家,咱先来看下一些常用的基本命令. 欢迎转载,转载请标明出处:http://blog.csdn.net/notbaron/article/details/48092873 1.  数字和表达式 看下图1一就能说明很多问题: 加法,整除,浮点除,取模,幂乘方等.是不是很直接也很粗暴. 关于上限,蛤蟆不太清楚

小猪的数据结构学习笔记(二)

小猪的数据结构学习笔记(二) 线性表中的顺序表 本节引言: 在上个章节中,我们对数据结构与算法的相关概念进行了了解,知道数据结构的 逻辑结构与物理结构的区别,算法的特性以及设计要求;还学了如何去衡量一个算法 的好坏,以及时间复杂度的计算!在本节中我们将接触第一个数据结构--线性表; 而线性表有两种表现形式,分别是顺序表和链表;学好这一章很重要,是学习后面的基石; 这一节我们会重点学习下顺序表,在这里给大家一个忠告,学编程切忌眼高手低,看懂不代表自己 写得出来,给出的实现代码,自己要理解思路,自己