MAVEN的初识

Maven

一、什么是Maven

Maven 是一个软件项目管理和理解工具。基于项目对象模型 (POM) 的概念,Maven利用一个中央信息片断能管理一个项目的构建、报告和文档等步骤。

二、Maven能做什么?

Maven 能够帮助开发者完成以下工作:
• 构建
• 文档生成
• 报告
• 依赖
• SCMs
• 发布
• 分发
• 邮件列表

三、Maven约定配置

• Maven 提倡使用一个共同的标准目录结构,Maven 使用约定优于配置的原则,大家尽可能的遵守这样的目录结构。如下所示

目录目的
src/main/java项目存放JAVA文件
/src/main/resources项目的资源,比如说property文件
src/test/java项目测试类,比如Junit
src/test/resources测试用的资源
src/main/webapp/WEB-INFweb应用文件目录,web项目的信息,比如web.xml,本地的图片
target打包输出目录
/target/classes编译输出目录
/target/test-classes测试编译输出目录
Test.javaMaven只会自动运行符合该命令名规则的测试类
~/.m2/repositoryMaven默认的本地仓库目录位置

Maven特点

  • 项目设置遵循统一规则。
  • 任意工程中共享。
  • 依赖管理包括自动更新。
  • 一个庞大且不断增长的库。
  • 可扩展,能够轻松编写Java或脚本语言的插件。
  • 只需要很少或不需要额外配置即可即时访问新功能。
  • 基于模型的构建,Maven能够将任意数量的项目构建到预定义的输出类型中。如JAR、WAR或基于项目元数据的分发,而不需要在大多情况下执行任何脚本。
  • 项目信息的一致性站点,使用与结构过程相同的元数据,Maven能够生成一个网站或PDF,包括你要添加的任何文档,并添加到关于项目开发状态的标准报告中。
  • 发布管理和发布单独的输出,Maven将不需要额外的配置,就可以与源代码管理系统(如Subversion或Git)集成,并可以基于某个标签管理项目的发布。它可以将其发布到分发位置供其他项目使用。
  • 向后兼容性,可以从旧版本Maven的多个模块移植到Maven3中。
  • 子项目使用父项目依赖时,正常情况子项目应该继承父项目的依赖,无需版本号。
  • 并行构建
  • 更好的报错,Maven改进了错误报告,提供了Maven wiki页面链接。

Maven构建生命周期

Maven构建生命周期定义了一个项目构建到发布的过程。
一个典型的Maven构建(build)生命周期是由以下几个阶段的序列组成的:

Maven生命周期详情

详情

Maven 有以下三个标准的生命周期:
  • clean:项目清理的处理
    当我们执行 mvn post-clean 命令时,Maven 调用 clean 生命周期,它包含以下阶段:
    • pre-clean:执行一些需要在clean之前完成的工作
    • clean:移除所有上一次构建生成的文件
    • post-clean:执行一些需要在clean之后立刻完成的工作

  • default(或 build):项目部署的处理
    这是 Maven 的主要生命周期,被用于构建应用,包括下面的 23 个阶段:

生命周期描述
validate(校验)校验项目是否正确并且所有必要的信息可以完成项目的构建过程。
initialize(初始化)初始化构建状态,比如设置属性值。
generate-sources(生成源代码)生成包含在编译阶段中的任何源代码。
process-sources(处理源代码)处理源代码,比如说,过滤任意值。
generate-resources(生成资源文件)生成将会包含在项目包中的资源文件。
process-resources (处理资源文件)复制和处理资源到目标目录,为打包阶段最好准备。
compile(编译)编译项目的源代码。
process-classes(处理类文件)处理编译生成的文件,比如说对Java class文件做字节码改善优化。
generate-test-sources(生成测试源代码)生成包含在编译阶段中的任何测试源代码。
process-test-sources(处理测试源代码)处理测试源代码,比如说,过滤任意值。
generate-test-resources(生成测试资源文件)为测试创建资源文件。
process-test-resources(处理测试资源文件)复制和处理测试资源到目标目录。
test-compile(编译测试源码)编译测试源代码到测试目标目录.
process-test-classes(处理测试类文件)处理测试源码编译生成的文件。
test(测试)使用合适的单元测试框架运行测试(Juint是其中之一)。
prepare-package(准备打包)在实际打包之前,执行任何的必要的操作为打包做准备。
package(打包)将编译后的代码打包成可分发格式的文件,比如JAR、WAR或者EAR文件。
pre-integration-test(集成测试前)在执行集成测试前进行必要的动作。比如说,搭建需要的环境。
integration-test(集成测试)在执行集成测试完成后进行必要的动作。比如说,清理集成测试环境。
post-integration-test(集成测试后)在执行集成测试完成后进行必要的动作。比如说,清理集成测试环境。
verify (验证)运行任意的检查来验证项目包有效且达到质量标准。
install(安装)安装项目包到本地仓库,这样项目包可以用作其他本地项目的依赖。
deploy(部署)将最终的项目包复制到远程仓库中与其他开发者和项目共享。
  • site:项目站点文档创建的处理
    Maven Site 插件一般用来创建新的报告文档、部署站点等。
    • pre-site:执行一些需要在生成站点文档之前完成的工作。
    • site:生成项目的站点文档。
    • post-site: 执行一些需要在生成站点文档之后完成的工作,并且为部署做准备。
    • site-deploy:将生成的站点文档部署到特定的服务器上。

Maven 仓库

在 Maven 的术语中,仓库是一个位置(place)。
Maven 仓库是项目中依赖的第三方库,这个库所在的位置叫做仓库。
在 Maven 中,任何一个依赖、插件或者项目构建的输出,都可以称之为构件。
Maven 仓库能帮助我们管理构件(主要是JAR),它就是放置所有JAR文件(WAR,ZIP,POM等等)的地方。
Maven 仓库有三种类型:
• 本地(local)
• 中央(central)
• 远程(remote)


本地仓库
Maven 的本地仓库,在安装 Maven 后并不会创建,它是在第一次执行 maven 命令的时候才被创建。
运行 Maven 的时候,Maven 所需要的任何构件都是直接从本地仓库获取的。如果本地仓库没有,它会首先尝试从远程仓库下载构件至本地仓库,然后再使用本地仓库的构件。
默认情况下,不管Linux还是 Windows,每个用户在自己的用户目录下都有一个路径名为 .m2/respository/ 的仓库目录。
Maven 本地仓库默认被创建在 %USER_HOME% 目录下。要修改默认位置,在 %M2_HOME%\conf 目录中的 Maven 的 settings.xml 文件中定义另一个路径。

<settings xmlns="http://maven.apache.org/SETTINGS/1.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/SETTINGS/1.0.0 http://maven.apache.org/xsd/settings-1.0.0.xsd"> 
<localRepository>C:/MyLocalRepository</localRepository> 
</settings>

当你运行 Maven 命令,Maven 将下载依赖的文件到你指定的路径中。

中央仓库
Maven 中央仓库是由 Maven 社区提供的仓库,其中包含了大量常用的库。
中央仓库包含了绝大多数流行的开源Java构件,以及源码、作者信息、SCM、信息、许可证信息等。一般来说,简单的Java项目依赖的构件都可以在这里下载到。
中央仓库的关键概念:
• 这个仓库由 Maven 社区管理。
• 不需要配置。
• 需要通过网络才能访问。
要浏览中央仓库的内容,maven 社区提供了一个 URL:http://search.maven.org/#browse。使用这个仓库,开发人员可以搜索所有可以获取的代码库。


远程仓库
如果 Maven 在中央仓库中也找不到依赖的文件,它会停止构建过程并输出错误信息到控制台。为避免这种情况,Maven 提供了远程仓库的概念,它是开发人员自己定制仓库,包含了所需要的代码库或者其他工程中用到的 jar 文件。
举例说明,使用下面的 pom.xml,Maven 将从远程仓库中下载该 pom.xml 中声明的所依赖的(在中央仓库中获取不到的)文件。

<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.companyname.projectgroup</groupId>
   <artifactId>project</artifactId>
   <version>1.0</version>
   <dependencies>
      <dependency>
         <groupId>com.companyname.common-lib</groupId>
         <artifactId>common-lib</artifactId>
         <version>1.0.0</version>
      </dependency>
   <dependencies>
   <repositories>
      <repository>
         <id>companyname.lib1</id>
         <url>http://download.companyname.org/maven2/lib1</url>
      </repository>
      <repository>
         <id>companyname.lib2</id>
         <url>http://download.companyname.org/maven2/lib2</url>
      </repository>
   </repositories>
</project>

Maven 依赖管理

Maven 一个核心的特性就是依赖管理。当我们处理多模块的项目(包含成百上千个模块或者子项目),模块间的依赖关系就变得非常复杂,管理也变得很困难。针对此种情形,Maven 提供了一种高度控制的方法。


可传递性依赖发现
A->B->C


A->B->C(0.2)

A->C(0.1)

最短路径原则: C(0.1)


A->B->C(0.2)

A->D->C(0.1)

优先声明原则:C(0.2)


传递性依赖的scope传递规则,与第一依赖和第二依赖有关,下表第一列表示第一依赖,第一行表示第二依赖
在这里插入图片描述
从上表我们可以轻松得到几点信息

  • 第二依赖为complie不改变第一依赖
  • 第二依赖test不传递依赖
  • 第二依赖provided只传递provided
  • 第二依赖runtime对compile第一依赖的传递依赖是runtime

依赖范围
传递依赖发现可以通过使用如下的依赖范围来得到限制:

范围描述
编译阶段该范围表明相关依赖是只在项目的类路径下有效。默认取值。
供应阶段该范围表明相关依赖是由运行时的 JDK 或者 网络服务器提供的。
运行阶段该范围表明相关依赖在编译阶段不是必须的,但是在执行阶段是必须的。
测试阶段该范围表明相关依赖只在测试编译阶段和执行阶段。
系统阶段该范围表明你需要提供一个系统路径。
导入阶段该范围只在依赖是一个 pom 里定义的依赖时使用。同时,当前项目的POM 文件的 部分定义的依赖关系可以取代某特定的 POM。

依赖管理
通常情况下,在一个共通的项目下,有一系列的项目。在这种情况下,我们可以创建一个公共依赖的 pom 文件,该 pom 包含所有的公共的依赖关系,我们称其为其他子项目 pom 的 pom 父。 接下来的一个例子可以帮助你更好的理解这个概念。
在这里插入图片描述

Maven坐标

一个完整的坐标信息,由 groupId、artifactId、version、packaging、classifier 组成,如下是一个简单的坐标定义。

<groupId>org.SpringFramework</groupId>
<artifactId>spring-core</artifactId>
<version>4.2.7.RELEASE</version>
<packaging>jar</packaging>

这是 JUnit 的坐标,下面详细介绍一下各个元素。
1. groupId
定义当前 Maven 项目从属的实际项目。关于 groupId 的理解如下所示。
1)Maven 项目和实际项目不一定是一一对应的。比如 SpringFramework,它对应的 Maven 项目就有很多,如 spring-core、spring-context、spring-security 等。造成这样的原因是模块的概念,所以一个实际项目经常会被划分成很多模块。
2)groupId 不应该同开发项目的公司或组织对应。原因比较好理解,一个公司和一个组织会开发很多实际项目,如果用 groupId 对应公司和组织,那 artifactId 就只能是对应于每个实际项目了,而再往下的模块就没法描述了,而往往项目中的每个模块是以单独的形式形成构件,以便其他项目重复聚合使用。
3)groupId 的表述形式同 Java 包名的表述方式类似,通常与域名反向一一对应。

2. artifactId
定义实际项目中的一个 Maven 项目(实际项目中的一个模块)。

推荐命名的方式为:实际项目名称-模块名称。

比如,org.springframework 是实际项目名称,而现在用的是其中的核心模块,它的 artifactId 为 spring-core。

3. version
定义 Maven 当前所处的版本。如上的描述,用的是 4.2.7.RELEASE 版本。需要注意的是,Maven 中对版本号的定义是有一套规范的。具体规范请参考《版本管理》的介绍。

4. packaging
定义 Maven 项目的打包方式。
打包方式通常与所生成的构件文件的扩展名对应,比如,.jar、.ear、.war、.pom 等。另外,打包方式是与工程构建的生命周期对应的。比如,jar 打包与 war 打包使用的命令是不相同的。最后需要注意的是,可以不指定 packaging,这时候 Maven 会自动默认成 jar。

5. classifier
定义构件输出的附属构件。
附属构件同主构件是一一对应的,比如上面的 spring-core-4.2.7.RELEASE.jar 是 spring-core Maven spring-core 项目的主构。
Maven spring-core 项目除了可以生成上面的主构件外,也可以生成 spring-core-4.2.7.RELEASE-javadoc.java 和 spring-core-4.2.7.RELEASE-sources.jar 这样的附属构件。这时候,javadoc 和 sources 就是这两个附属构件的 classifier。这样就为主构件的每个附属构件也定义了一个唯一的坐标。
最后需要特别注意的是,不能直接定义一个 Maven 项目的 classifier,因为附属构件不是由 Maven 项目构建的时候直接默认生成的,而是由附加的其他插件生成的。
前面介绍的组成坐标的 5 个要素中,groupId、artifactId 和 version 是必需的,packaging 是可选的,默认是 jar,而 classifier 是不能直接定义的。同时,Maven 项目的构件文件名与坐标也是有对应关系的,一般规则是 artifactId-version[-classifier].packaging。

Maven常用命令及其作用

命令名称作用
maven clean对项目进行清理,删除target目录下编译的内容
maven compile编译项目源代码
maven test对项目进行运行测试
maven packet打包文件并存放到项目的target目录下,打包好的文件通常都是编译后的class文件
maven install在本地仓库生成仓库的安装包,可供其他项目引用,同时打包后的文件放到项目的target目录下

一、常用命令使用场景举例
1、mvn clean package依次执行了clean、resources、compile、testResources、testCompile、test、jar(打包)等7个阶段
package命令完成了项目编译、单元测试、打包功能,但没有把打好的可执行jar包(war包或其它形式的包)布署到本地maven仓库和远程maven私服仓库
2、mvn clean install依次执行了clean、resources、compile、testResources、testCompile、test、jar(打包)、install等8个阶段
install命令完成了项目编译、单元测试、打包功能,同时把打好的可执行jar包(war包或其它形式的包)布署到本地maven仓库,但没有布署到远程maven私服仓库
3、mvn clean deploy依次执行了clean、resources、compile、testResources、testCompile、test、jar(打包)、install、deploy等9个阶段
deploy命令完成了项目编译、单元测试、打包功能,同时把打好的可执行jar包(war包或其它形式的包)布署到本地maven仓库和远程maven私服仓库
二、常见问题
(一)mvn clean install 和 mvn install 的区别
1、根据maven在执行一个生命周期命令时,理论上讲,不做mvn install 得到的jar包应该是最新的,除非使用其他方式修改jar包的内容,但没有修改源代码
2、平时可以使用mvn install ,不使用clean会节省时间,但是最保险的方式还是mvn clean install,这样可以生成最新的jar包或者其他包
(二)maven两种跳过单元测试方法的区别
1、 mvn package -Dmaven.test.skip=true
不但跳过了单元测试的运行,同时也跳过了测试代码的编译
2、 mvn package -DskipTests
跳过单元测试,但是会继续编译。如果没时间修改单元测试的bug,或者单元测试编译错误,则使用第一种,不要使用第二种

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值