Maven之我见

学习新技能
本篇文章主要是记录学习过程中遇到的一些问题,而不是教学

一、What


maven是一个项目管理工具,可以通过一小段描述信息来管理项目的构建,报告和文档的软件项目。
Maven 是一个强大的项目管理和构建自动化工具,它通过抽象项目对象模型和构建生命周期模型来对项目及其构建过程进行管理。Maven 最大化的消除了构建的重复,提升了构建的效率与标准化。除此之外,Maven 还有依赖管理、自动生成项目站点、代码静态检查等特性。

什么是构建工具?
构建工具是将软件项目构建相关的过程自动化的工具。构建一个软件项目通常包含以下一个或多个过程:

  • 生成源码(如果项目使用自动生成源码);
  • 从源码生成项目文档;
  • 编译源码;
  • 将编译后的代码打包成JAR文件或者ZIP文件;
  • 将打包好的代码安装到服务器、仓库或者其它的地方;

有些项目可能需要更多的过程才能完成构建,这些过程一般也可以整合到构建工具中,因此它们也可以实现自动化。

自动化构建过程的好处是将手动构建过程中犯错的风险降到最低。而且,自动构建工具通常要比手动执行同样的构建过程要快。
目前个人对maven用途的理解主要有以下

  1. 消除构建的重复:
    如果项目需要引入的多个A、B包,而他们的实现都需要C包。传统模式下,A包和B包都会将C包放到自己的jar包中,这样引入单独的A包或者B包的时候就不需要再引入其他包。但是这就造成了如果同时需要A包和B包,就会在项目中出现两个C包。而Maven的出现可以让A包B包专心自己的代码,将需要的C包通过Maven引入,同时在用Maven引入A包和B包的时候能够识别只引入一个C包。
  2. 打包:
    项目在开发时为了启动速度使用Jetty作为web容器,希望在生产环境能够使用Tomact。则可以使用Maven的依赖范围scope中的provided,来实现编译时用Jetty包,运行(打包后)时不引入Jetty包,从而可以直接放到Tomact容器中运行而不会冲突。

<br />

二、Maven项目目录结构


maven目录结构、web项目目录结构

Maven目录结构

这是一个Maven项目的目录结构。正常情况下,用不同的框架或者方式建立的web项目,在开发时为了满足各自的自身需求会有不同的目录结构,但在发布的时候就会发布一个统一的目录结构,这一点需要注意。而在eclipse下,我们可以在project-properties-Deployment Assembly中设置发布时各个文件的输出目录。 以下为web项目目录的标准结构

web项目目录结构

上述文件和文件夹是一个web项目必备的。web容器初始化后会先根据WEB-INF中的web.xml解析客户端请求,然后返回相应的资源。
比如请求/admin/login,服务器会先根据web.xml查找并执行class中相应的类文件。然后在通过各类文件中的路径去寻找需要访问的资源(properties、css、jsp等等)。

<br />

三、仓库


maven的仓库有两类:1.本地仓库 2.远程仓库。
其中远程仓库又有以下:2.1中央仓库、2.2私服、2.3其他仓库。
maven项目引用jar包是根据顺序

  1. 当依赖的范围是system(默认)的时候先从本地查找jar包
  2. 如果本地没有,则去中央仓库下载。
  3. 当发现setting.xml中配置了中央仓库的镜像后,去该镜像地址下载。

ps:建立改变本地仓库位置,避免重装以后要重新下载;同时配置仓库镜像,这样下载镜像是能更。

<br />

四、Maven的依赖


1.依赖包的查询是根据坐标来进行的,先查询本地查询再去中央仓库

2.依赖范围scope见下图...................................

maven依赖范围

根据Java 面试题问与答:编译时与运行时Java泛型依赖的官方文档

这里的一些概念需要理解,比如编译测试并不是指我们平时说的编译,而是一个具体的命令。如下图的mvn compile,实际上指编译特定目录下的文件。这里在看上面的test,意思是只有当用测试命令的时候才会引入这个包。

Maven命令列表

重点理解provided,servlet经常用。

3.依赖具有传递性。
对于依赖的传递而言,主要是针对compile作用域传递

当传递冲突时:

  • 第一声明者优先原则:
    【a-->b1.0】 【c-->b1.1】 【d-->a和c】,这个时候在d的pom中,哪一个依赖先写就使用先写依赖的版本,所以是b1.0

  • 路径近者优先原则:
    【a-->b1.0】 【c-->b1.1】 【d-->a和c-->b1.0】 f-->d,c,如果路径的长短不一致就选择最小路径,所以是b1.1

  • 如果希望精确的控制依赖包,可以使用依赖的排除功能进行控制

<exclusions>
    <exclusion>
        <groupId>lo4j</groupId>
        <artiffactId>log4j</artiffactId>
    </exclusion>
</exclussons>

4.依赖的聚合和继承
maven聚合:聚合实际上是对多个项目同时进行做处理,比如编译、打包等。做法如下:创建一个新的maven项目,用于做其它项目的聚合,然后把pom.xml文件里的package标签里的jar改成pom,并去掉依赖,然后添加modules把其它项目引进来。
maven继承:继承实际上是把相同的依赖提取出来,放到一个父级项目的dependencyManagement标签里,然后子项目通过parent标签父级项目引进来。
问题2:有两种打包war的方式

5.版本管理
总版本号.分支版本号.小版本号-里程碑版本
总版本号的变动一般表示框架的变动
分支版本号:一般表示增加了一些功能
小版本号:在分支版本上面进行bug的修复
里程碑:SNAPSHOT快照-->alpha内部测试-->beta公测-->release稳定-->GA正式发布

<br />

四、生命周期


Maven的生命周期就是对所有的构建过程进行抽象和统一。包含了项目的清理、初始化、编译、测试、打包、集成测试、验证、部署和站点生成等几乎所有的构建步骤。
Maven的生命周期是抽象的,即生命周期不做任何实际的工作,实际任务由插件完成,类似于设计模式中的模板方法。

三套独立的生命周期

1、clean生命周期:清理项目,包含三个phase。

  • pre-clean:执行清理前需要完成的工作
  • clean:清理上一次构建生成的文件
  • post-clean:执行清理后需要完成的工作

2、default生命周期:构建项目,重要的phase如下。

  • validate:验证工程是否正确,所有需要的资源是否可用。
  • compile:编译项目的源代码。
  • test:使用合适的单元测试框架来测试已编译的源代码。这些测试不需要已打包和布署。
  • Package:把已编译的代码打包成可发布的格式,比如jar。
  • integration-test:如有需要,将包处理和发布到一个能够进行集成测试的环境。
  • verify:运行所有检查,验证包是否有效且达到质量标准。
  • install:把包安装到maven本地仓库,可以被其他工程作为依赖来使用。
  • Deploy:在集成或者发布环境下执行,将最终版本的包拷贝到远程的repository,使得其他的开发者或者工程可以共享。

3、site生命周期:建立和发布项目站点,phase如下

  • pre-site:生成项目站点之前需要完成的工作
  • site:生成项目站点文档
  • post-site:生成项目站点之后需要完成的工作
  • site-deploy:将项目站点发布到服务器

命令行和生命周期

各个生命周期相互独立,一个生命周期的阶段前后依赖。
举例如下:

1、mvn clean
调用clean生命周期的clean阶段,实际执行pre-clean和clean阶段

2、mvn test
调用default生命周期的test阶段,实际执行test以及之前所有阶段

3、mvn clean install
调用clean生命周期的clean阶段和default的install阶段,实际执行pre-clean和clean,install以及之前所有阶段

推荐阅读更多精彩内容

  • Spring Cloud为开发人员提供了快速构建分布式系统中一些常见模式的工具(例如配置管理,服务发现,断路器,智...
    卡卡罗2017阅读 121,074评论 16 134
  • 所有项目的构建都是有生命周期的,这个生命周期包括:项目清理、初始化、编译、测试、打包、集成测试、验证、部署、站点生...
    zlcook阅读 2,243评论 0 21
  • Android 自定义View的各种姿势1 Activity的显示之ViewRootImpl详解 Activity...
    passiontim阅读 157,663评论 24 688
  • 生活的活
    凡人and趣魂阅读 88评论 0 1
  • 在我们从孩子变为成人的过程中,我们总会遇见那么几个人。他的一言一行都牵动着你的心,他的一举一动都紧紧抓住你的眼...
    起飞吧楚楚楚阅读 351评论 10 5