《Maven 实战》

SQ3R:
Survey
1、这本书是国内首个Maven著作,而并非 xx in action的翻译;
2、基于Maven 3;
 
question
1、Maven这一优秀的技术为什么没有得到广泛的推广?
         Maven陡峭的学习曲线、文档匮乏
 
2、Maven的前世今生??
 
3、什么情境下诞生了Maven?
 
4、Maven主要是用来做什么的?
         跨平台的项目管理工具、自动化构建、依赖管理,使项目经理更高效、规范地管理项目
 
5、Maven与Ant的区别?
  • Maven
    • 自动化构建、管理项目
    • 跨平台
    • 为全世界java开发者提供中央仓库,自动下载构件
    • 对第三方类库进行依赖管理
    • 管理分散在项目各个角落的项目信息:项目描述、开发者列表、版本控制系统、许可证、缺陷管理系统地址等
    • 对项目的目录结构、测试用例命名方式等都有既定的规则,遵循既定规则,免去学习成本,即约定优于配置(Convention Over Configuration)
  • Ant
    • 只能是自动化构建,不能进行项目管理
    • 跨平台
 
 
read

第一章 Maven简介

1、何为Maven?

  • 跨平台的项目管理工具
  • 服务于基于java平台的项目构建、依赖管理、项目信息管理
  • 能够管理的项目规模:从小型的开源类项目到大型的企业级应用
  • 能够适用于的开发模式:从最早的瀑布模型到最新的敏捷开发

2、Maven与构建管理工具的比较

         比喻:购买品牌电脑  vs  自己组装电脑
        当你需要一个电脑时,Maven更像是直接购买一个品牌电脑,而其他工具更像是自己动手组装一台电脑;前者让你省时省力,好能享受售后服务,后者享受组转过程但是费时费力,还不太稳定。
  • IDE工具:IDE不是万能
    • 优点
      • IDE能够提供强大的文本编辑、调试甚至重构功能
    • 缺点
      • 依赖大量的手工操作:编译、测试、代码生成等工作相互独立,难以一键完成,低效、易出错
      • 难以在项目中统一所有的IDE配置,每个人都有自己的喜好,造成一个在机器A上运行的任务在机器B上运行失败
    • 总结:不能过于依赖IDE,集成Maven,在IDE中使用Maven
  • make:最早的构建工具
    • 优点
      • make由一个名为Makefile的脚本文件进行驱动,使用make自己定义的语法,基本组成部分是一系列的Rules、Targets、Prerequisite、Command,将整个构建过程串联起来
      • 极大限度地利用系统的本地命令,以系统耦合紧密
    • 缺点
      • 与操作系统耦合紧密,不能实现跨平台,对java相当不友好
      • makefile的语法容易出错
  • Ant:Another Neat Tool(意为“另一个整洁的工具”,而非“蚂蚁”)
    • 优点
      • 最早用来构建Tomcat,因为作者受不了make的语法格式而创造Ant
      • Ant可以看成是java版本的make,解决了make的跨平台问题;Ant使用XML文件,解决了makefile的语法格式问题
    • 缺点
      • Ant是过程式的,开发者显式地制定每一个目标,以及完成该目标需要执行的任务(Maven是声明式的,构建过程基本都有现成的插件实现,开发者只需声明项目的基本元素即可)
      • 针对每一个项目,都要重新编写一遍这一过程,隐含很大的重复(Maven开发者声明了项目基本元素之后,由Maven执行内置的构建过程,消除大部分重复)
      • Ant原来没有依赖管理,现在可以依赖Ivy进行依赖管理(Maven内置了依赖管理功能)

3、Maven目前存在的问题

  • Maven比较复杂
    • Maven是用来管理项目的,而清理、编译、测试、打包、发布等这一过程本身就很复杂,所以我们要做的是帮助Maven变得简单;
  • Maven的中央仓库比较混乱
    • Maven的中央仓库确实不完美,甚至会发现某个jar包出现在两个不同的路径下,,这不是Maven的错,而是开源项目本身改变了自己的坐标,所以我们可以建立自己组织内部的仓库服务器,这会为你带来意想不到的好处。
  • Maven缺乏文档
    • 这个确实是事实,maven的站点文档比较凌乱。
 

第二章 Maven的安装与配置

1、在windows下安装

  • 安装JDK
  • 下载Maven压缩包、解压、设置环境变量%M2HOME%
  • 加入path路径下,ok!

2、基于UNIX系统上安装(略)

 

3、Maven安装目录分析

  • bin
    • 包含mvn运行的脚本,这些脚本用来配置java命令,准备好classpath和相关的java属性,然后执行java命令。
  • boot
    • 只包含一个jar文件,是maven自己的类加载器框架,相比java的类加载器框架,它提供了更丰富的语法以方便配置。
  • conf
    • 包含有重要文件settings.xml,修改该文件可以在全局上定制maven行为;
    • 一般会把该文件复制到~/.m2/目录下,在用户范围内定制Maven行为(~表示用户目录,如C:\user\xxx\,C:\Document and Settings\XXX\)
  • lib
    • 放置maven自身需要的一些jar包
  • LINCENSE.TXT
  • NOTICE.TXT
  • README.TXT

4、设置HTTP代理

  • 复制settings.xml文件至~/.m2/目录,修改其中的<proxies>标签中内容

5、安装m2eclipse插件

  • eclipse是一个强大的IDE,集成了很多工具,JUnit、CVS、SVN等,但是没有集成Maven
  • Maven之父Jason Val Zyl为我们制造了m2eclipse插件
  • 安装可能出现问题:更换eclipse默认的JRE

6、安装netbeans Maven插件

  • 6.7以上的版本已经预装了Maven插件

7、Maven安装最佳实践

  • 设置MAVEN_OPTS环境变量
    • 设置MAVEN_OPTS环境变量的值为-Xms128m -Xmx512m,
    • 因为mvn实际上是运行java命令,而java默认的内存往往不能够满足Maven的运行需要,所以需要该配置;
  • 配置用户范围的settings.xml
    • 复制settings.xml文件到~/.m2/目录,修改后结果只影响到机器上这一用户,不能影响系统下其他用户;
    • 直接修改conf文件夹下settings.xml会影响到整个机器上的Maven行为
  • 不要使用IDE内嵌的Maven
    • IDE内的maven一般会比较新(如果是新版本的IDE的话),这样的Maven不是很稳定
    • 除了在IDE内部,其他时候我们会使用命令行的Maven,如果版本不一样,会造成不一样的结果,算是IDE不是万能的一条吧
 

第三章 Maven使用入门

1、编写POM

  • 就像ant中的build.xml一样,Maven中需要编写pom.xml(Project Object Model 项目对象模型)
  • pom.xml文件的组成(只有一个根元素,五个子元素)
    • 根元素<project>,这点跟build.xml一样
    • <modelVersion>:对于maven2和maven3,只能是4.0.0
    • <groupId>:定义项目属于哪个组,如com.google.myapp,
    • <artifactId>:定义当前项目在<groupId>中的唯一ID,如hello-world
    • <version>:定义当前<groupId>中当前<artifactId>项目的版本号
    • <name>:没有实际意义,但是推荐一个有意义的项目名字
  • pom.xml中不涉及任何java代码,与项目代码相对立(解耦),很大程度上避免了java代码和POM代码的相互影响
  • 向项目需要升级时,只需修改POM,不需修改java代码;而当POM稳定之后,日常的java代码开发工作不涉及POM代码

2、编写主代码

  • 项目主代码会被打包到项目最终的构件中(如jar),项目测试代码则不会
  • 约定存在主代码目录:src.main.java
  • 约定java类的包名:与pom.xml中的groupId、artifactId一致

3、编写测试代码

  • 约定项目测试代码目录:src.test.java
  • 要使用JUnit进行测试,需要在pom.xml中添加JUnit依赖

4、打包和运行

  • 命令:mvn clean package
  • 命令:mvn clean install
  • 命令:mvn clean compile

5、使用Archetype生成项目骨架

  • 针对maven3:mvn archetype:generate
  • 根据提示输入groupId、artifactId等信息
  • 自动生成各种约定好的文件夹结构

6、m2eclipse的简单使用(略)

7、netbeans maven插件简单使用(略)

第四章 背景案例(略)

第五章 坐标和依赖

1、何为Maven坐标?

  • 用坐标去确定唯一的构件,即jar、war等文件
  • Maven定义:世界上任何一个构件都可以使用Maven坐标唯一标示
  • Maven坐标的元素:groupId、artifactId、version、packaging、classifier。

2、Maven坐标详解

  • groupId(必须)
    • 定义当前Maven项目隶属的组织机构中实际存在的项目
    • 不要对应在组织机构层(组织机构层范围太大
    • Maven项目和实际存在项目不一定是一对一的关系实际存在项目包括多个Maven项目
  • artifactId(必须)
    • 对应组织机构中实际存在项目中的某个Maven模块
  • version(必须)
    • 定义当前Maven模块的版本号
  • packaging(可选)
    • 定义Maven项目的打包模式,jar、war等
  • classifier(不能直接定义)
    • 帮助定义构建输出的一些附属构件,如xxx-javadoc.jar、xxx-sources.jar等

3、依赖配置的基本元素

  • groupId、artifactId、version:依赖的基本坐标,最重要
  • type:依赖的类型,对应于项目坐标定义的packaging,大部分情况下不用声明,默认为jar
  • scope:依赖的作用范围
  • optional:标记依赖是否可选
  • exclusions:用来排除传递性依赖、

4、依赖范围

  • Maven项目有三种classpath(编译classpath、测试classpath、运行classpath);
  • 依赖范围就是控制依赖(如junit等)与这三张classpath的关系
  • 依赖范围的分类
    • compile——编译依赖范围,是Maven的默认依赖范围对编译、测试、运行classpath都有效
    • test——测试依赖范围,只对测试classpath有效
    • provided——已提供依赖范围,只对编译、测试有效。对运行无效;
    • runtime——运行时依赖范围,对测试、运行有效,对编译无效;
    • system——系统依赖范围,与provided一致,但是与系统绑定,易造成不可移植,慎用;
    • import——导入依赖范围,对三类classpath没有实际影响

5、传递性依赖

  • 什么叫传递性依赖?
    • A.jar在compile范围内依赖B.jar,B.jar在compile范围内依赖C.jar,所以A.jar在compile范围内依赖C.jar

    • 省去了手动添加jar包的问题
  • 传递性依赖和依赖范围
    • A——>B:第一直接依赖范围
    • B——>C:第二直接依赖范围
    • A——>C:传递性依赖范围
 

6、依赖调解

  • 传递性依赖存在的问题
    • 在项目A中:A——>B——>C——>X(1.0);A——>D——>X(2.0);X是A的传递性依赖,但是两个路径上的X版本不同,此时应该选择哪个X?
    • 在项目A中:A——>B——>X(1.0);A——>D——>X(1.0);X是A的传递性依赖,但是路径相同,此时应该选择哪个X?
  • 解决两个问题的原则
    • 原则一:路径不同时,路径最短者优先
    • 原则二:路径相同时,第一声明者优先

7、可选依赖

  • 可选依赖不会传递
  • 尽量不使用可选依赖

8、最佳实践

  • 排除依赖——排除传递性依赖
    • 传递性依赖会出现以下隐患:A—>B—>C,但是B中对C的依赖可能是一个不稳定的版本,会造成A失败;
    • 使用<exclusion>排除依赖,然后再显式地声明依赖,即把依赖关系A—>B—>C,变成A—>B,A—>C,并在显式依赖中指定稳定版本的版本号,去除依赖不稳定版本的隐患

  • 归类依赖——与代码重构的思想相同,用变量代替常量
    • 比如:在项目中存在对Spring Framework的依赖,有org.springfarmework:spring-core:2.5.6、org.springfarmework:spring-context:2.5.6org.springfarmework:spring-beans:2.5.6org.springfarmework:spring-context-support:2.5.6,他们来自同一项目不同模块,当Spring Framework升级时,他们的版本号会一同升级,所以借鉴代码重构的思想,应该用变量代替常量
    • 使用<properties>标签,定义变量,在<version>标签中使用${元素名}代替常量;如

  • 优化依赖——同样是重构的思想,经常对依赖进行重构、优化
    • 程序员应该对Maven项目的依赖了然于胸,经常进行优化,去除多余的依赖,显示声明必要的依赖;
    • 对于存在冲突的依赖,进过两个原则之后,只会存在一个版本的依赖,这些依赖成为已解析依赖(Resolved Dependency
    • 使用命令mvn dependency:listmvn dependency:tree查看项目依赖
    • 使用mvn dependency:analyze进行分析,查看Used undeclared dependencies和Unused declared dependencies
    • Used undeclared dependencies(使用了未显式声明的依赖):存在风险,尽快排除
    • Unused declared dependencies(没有使用显式声明的依赖):这种依赖不能盲目删除,因为该命令只是分析编译,并不能分析测试和运行
 

第六章 仓库

1、何为仓库?

  • 存在jar、war等各种构件的地方
  • 分为本地仓库(只有一个)和远程仓库(可以有很多)两种,可类比为自己家的书房(只一个)和书店(很多),各种构件就是各种书籍
  • 本地仓库的存放位置:.m2/repository/,可以在.m2/settings.xml中修改仓库存放路径
  • 仓库的布局
    • 路径与坐标的对应关系为groupId/artifactId/version/artifactId-version.packaging,如groupId=org.testng、artifactId=testng、version=5.8、classifier=jdk1.5、packaging=jar,那么仓库中路径为:org/testng/testng/5.8/testng-5.8-jdk1.5.jar

2、本地仓库、远程仓库、中央仓库、私服

  • 本地仓库在刚安装Maven时是空的,必须执行Maven命令后才会生成;
  • 由于最开始本地仓库是空的,Maven必须知道一个远程仓库才能下载构件到本地仓库,这个默认的远程仓库就是中央仓库(Maven安装时自动配置了中央仓库);
  • 私服是特殊的远程仓库,架设在局域网内部,供局域网内部Maven项目使用
  • 当本地Maven项目需要下载构件时,先去私服请求,如果私服没有,则去远程仓库请求,从远程仓库下载构件后,把构件缓存在私服上,为下次请求服务。
  • 本地Maven项目也可以上传构件到私服

  • 建立私服的好处——即使在一台直接接入internet的个人机器上也应该设立私服
    • 节省外网带宽——直接从私服下载,不用经过外网
    • 加速Maven构建——下载速度更快
    • 部署第三方构件——上传构件,供他人使用
    • 提高稳定性,增强控制——Maven的构建高度依赖于远程仓库,当internet连接不稳定时,Maven甚至无法构建,设立私服后,不存在该问题
    • 降低中央仓库的负荷——维护一个中央仓库费时、费财、费力

3、远程仓库的配置

  • 一个Maven项目会用到很多构件,来自不同的远程仓库,可以在pom.xml中使用<repository>进行配置
  • 一般不需要认证即可下载,需要认证时,使用<server>标签进行配置用户名及密码
  • 部署构件到远程仓库时,使用<distributionManagement>标签

4、快照版本

  • 小李在开发模块A,小张在开发模块B,B依赖A,但是A还没有稳定版本,但是B希望总是使用A的最新版本进行构建
  • 设置A的版本为2.1-SNAPSHOT发布到私服上,Maven在发布过程中会自动打上时间戳,而B在构建时,会根据时间戳自动寻找A的最新版本
  • 当项目发布时,只用把快照版本改为稳定版本即可

5、从仓库解析依赖的机制(即如何根据依赖的版本从仓库获取构件)

6、镜像

  • 如果仓库A可以提供仓库B存储的所有内容,那么仓库A就是仓库B的一个镜像(A>=B
  • 可以在settings.xml中修改<mirror>标签内容,选择速度最快的镜像

7、仓库搜索服务——如何根据项目依赖的构件名称得到构件的具体坐标

  • Sonatype Nexus——目前最流行的开源Maven仓库管理软件
  • Jarvana
  • MVNbrowser
  • MVNrepository

 

第七章 生命周期及插件

1、生命周期

  • Maven生命周期是为了对所有的构建过程进行抽象和统一;
  • Maven生命周期包括了项目的清理、初始化、编译、测试、打包、集成测试、验证、部署和站点生成等几乎所有的构建步骤;
  • 但是Maven生命周期不是一个整体,Maven生命周期拥有相互独立的三套生命周期,clean、default、site
  • clean生命周期——清理项目
    • pre-clean:执行清理前需要完成的工作;
    • clean:清理上一次构建生成的文件;
    • post-clean:执行一些清理后需要完成的工作;
  • default生命周期——定义了真正构建时所需要执行的步骤
    • validate
    • initialize
    • generate-sources
    • process-sources:处理项目主资源文件,进行变量替换、复制文件到classpath目录等工作
    • generate-resources
    • process-resources
    • compile:编译项目主源码,输出到主classpath目录
    • process-classes
    • generate-test-sources
    • process-test-sources:处理项目测试资源文件,变量替换、复制文件到classpath目录等工作
    • generate-test-resources
    • process-test-resources
    • test-compile:编译项目的测试代码,输出到主classpath目录
    • process-test-classes
    • test:使用单元测试框架进行测试
    • prepare-package
    • package:接受编译好的代码,打包成可发布格式
    • pre-integration-test
    • integration-test
    • post-integration-test
    • verify
    • install:将包上传到本地Maven仓库,供他人使用
    • deploy:将最终的包复制到远程仓库,供他人使用
  • site生命周期——建立和发布项目站点
    • pre-site
    • site:生成项目站点文档
    • post-site
    • site-deploy:将生成的项目站点发布到服务器上
  • 命令行与生命周期
    • mvn clean:clean生命周期中pre-clean、clean;
    • mvn test:default生命周期中从validate直到test阶段;
    • mvn clean install:clean生命周期中pre-clean、clean;default生命周期中从validate直到install阶段;
    • mvn clean deploy site-deploy:clean生命周期中pre-clean、clean;default生命周期中所有阶段;site生命周期中所有阶段;

2、插件目标与绑定

  • 一个插件中会包含n个功能,这n个功能就是n个插件目标;
  • Maven生命周期中的任务都是通过插件完成的,生命周期与插件相互绑定;

  • 内部绑定的插件目标与生命周期阶段——生命周期中没有绑定的其他阶段,因为没有插件目标,所以没有实际的行为

  • 用户自定义的绑定——通过自定义绑定,实现更强大的任务

3、插件配置

  • 在完成插件与生命周期的绑定之后,需要进行插件参数的配置,有命令行参数配置、POM中插件全局配置、POM中插件任务配置
 

第八章 聚合与继承

1、聚合——为了同时构建多个Maven模块

  • 聚合时首先要建立聚合文件夹聚合pom.xml文件;
  • 聚合文件夹中只包含聚合pom.xml,可以与被聚合模块是父子关系或者是平行关系;
  • 聚合pom.xml中的packaging类型只能是pom;
  • 使用<moduel>标签声明被聚合的Maven子模块;

2、继承——消除聚合时的重复,子模块继承父模块的定义

  • 格式与聚合类似,首先要建立父类文件夹聚合父类pom.xml文件;
  • 父类文件夹中只包含父类pom.xml;
  • 父类pom.xml中的packaging类型只能是pom
  • 聚合模块和父类模块可以合二为一!

3、反应堆(Reactor)——指Maven项目中所有Maven模块组成的构建结构

  • 反应堆的构建顺序:读取POM文件,优先构建依赖模块,其次按声明顺序构建各个模块;
  • 裁剪反应堆:即单独构建反应堆中的某一个模块,使用命令mvn -h查看命令
 
 

第九章 使用Nexus创建私服(略)

第十章 使用Maven进行测试(略)

第十一章 使用Hudson进行持续集成(略)

第十二章 使用Maven构建web应用:Cargo实现自动化web部署(略)

第十三章 版本管理

  • 区分版本管理(快照版、发布版等)和版本控制系统(SVN、CVS等);
  • GPG实现构件签名

第十四章 灵活的构建——针对不同的环境灵活配置、构建

第十五章 生成项目站点——定义关于该项目的所有信息(各种报告、界面等)

第十六章 m2eclipse——使用m2eclipse进行Maven项目开发

第十七章 编写Maven插件

第十八章 Archetype——快速生成项目骨架,深入解析Archetype

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值