Maven

来源:互联网 发布:黑魂3男捏脸数据 编辑:程序博客网 时间:2024/06/08 19:21

Maven

Maven简介

介绍Maven前,我们要先弄清楚什么是构建?

我们工作时,除了编写源代码,每天有一部分时间都花在了编译、运行单元测试、生成文档、打包和部署上面,这就是构建。多次重复的做这种工作,浪费了大量程序员的时间,所以有人用软件使这一系列操作完全自动化,只需要一条命令,这些繁琐的操作会很快完成。

强大的Maven

Maven是基于项目对象模型(POM),可以通过一小段描述信息来管理项目的构建,报告和文档的软件项目管理工具。是一个异常强大的构建工具,能帮我们自动化构建过程,从编译、运行单元测试、生成文档、打包和部署,我们只需要输入见得的Maven命令即可。

Maven是java编写的,因此可以跨平台。总的来说,Maven 简化了工程的构建过程,并对其标准化。它无缝衔接了编译、发布、文档生成、团队合作和其他任务。Maven 提高了重用性,负责了大部分构建相关的任务

Maven不仅仅是构建工具,还是依赖管理工具和项目信息管理工具,还有一个强大的功能就是能够自动下载项目依赖的第三方库,Maven通过坐标来准确的定位到每一个jar包,并自动帮我们下载。

Maven的安装和配置

1.先从官网下载Maven,我这里下载的最新版 apache-maven-3.5.0-bin 
2.下载成功后要配置Maven环境变量

这里写图片描述

这里写图片描述

3.测试是否安装成功,在系统命令行中执行命令:mvn –v

这里写图片描述

4.在Maven安装的目录的conf下有settings.xml文件,这是Maven的全局配置文件  我们可以在这儿配置本地仓库的地址,仓库后面会详解,里面会存放Maven下载的插件等 仓库地址默认系统的用户目录下的.m2/repository  我们自己来改变一下,当然我们

这里写图片描述

5.我们先运行一条简单的命令 mvn help:system,该命令会打印出所有的java系统属性和环境变量。运行这条命令主要目的是第一次运行Maven命令时,会自动下载Maven的插件,包括pom文件和jar,都被下载到了本地仓库中。  

这里写图片描述

这里写图片描述

简单的Maven入门项目

安装好Maven后,我们来手动搭建一个简单的Maven项目,Maven项目是约定大于配置,有固定的结构。

Maven项目的结构Project    |--src(源码包)        |--main(正常的源码包)            |--java(.java文件的目录)            |--resources(资源文件的目录)        |--test(测试的源码包)            |--java            |--resources    |--target(class文件、报告等信息存储的地方)    |--pom.xml(maven工程的描述文件) 
1.我们创建一个HelloWorld的项目,按照Maven项目的结构创建  只需创建src和pom.xml即可,target文件夹Maven会帮我们生成    

这里写图片描述

2.我们来编写一下pom.xml ,Maven的核心是pom.xml,pom定义了项目的基本信息,描述项目如何构建,声明项目依赖等。<?xml version="1.0" encoding="UTF-8"?><!--project是pom文件根元素,声明了一些命名空间--><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">  <!-- 指定了当前POM模型的版本,只能是4.0.0 -->  <modelVersion>4.0.0</modelVersion>  <!-- groupId 组织名称,定义了项目属于哪个组 -->  <groupId>com.cad.maven</groupId>  <!-- artifactId,定义了当前项目在组中的唯一标识。一般是项目名称 -->  <artifactId>HelloWorld</artifactId>  <!-- 当前项目版本号:每个工程发布后可以发布多个版本,依赖时调取不同的版本,使用不同的版本号 -->  <version>0.0.1</version>  <!-- 名称:可省略,提供一个更友好的名称 -->  <name>Hello</name></project>
3.创建主代码HelloWorld.java,放在src/main/java 下面 ,该类的包名和类名应该和pom中定义的groupId和artifactId一样     package com.cad.maven;    public class HelloWorld{        public String sayHello(String name){            return "hello"+name;        }    }
4.使用Maven进行编译,在项目根目录下使用命令 mvn -compile  第一次编译还是会下载很多插件,jar包等  编译成功后会在项目根目录下生成target目录,里面包含了.class文件和一些信息    

这里写图片描述

编写测试代码

1.测试代码按照约定应该位于src/test/java 路径下,我们使用我们熟悉的junit来进行测试,但是我们没有jar包,这时候我们可以使用maven为我们添加一个jUnit依赖 <?xml version="1.0" encoding="UTF-8"?><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">  <!-- 版本:4.0.0 -->  <modelVersion>4.0.0</modelVersion>  <!-- 组织名称:暂时使用 组织名称+项目名称 作为组织名称 -->  <!-- 组织名称:实际名称 按照访问路径规范设置,通常以功能作为名称:eg: junit spring -->  <groupId>com.cad.maven</groupId>  <!-- 项目名称 -->  <artifactId>HelloWorld</artifactId>  <!-- 当前项目版本号:同一个项目开发过程中可以发布多个版本,此处标示0.0.1版 -->  <!-- 当前项目版本号:每个工程发布后可以发布多个版本,依赖时调取不同的版本,使用不同的版本号 -->  <version>0.0.1</version>  <!-- 名称:可省略 -->  <name>Hello</name>  <!-- 依赖关系 -->    <dependencies>        <!-- 依赖设置 -->        <dependency>            <!-- 依赖组织名称 -->            <groupId>junit</groupId>            <!-- 依赖项目名称 -->            <artifactId>junit</artifactId>            <!-- 依赖版本名称 -->            <version>4.9</version>            <!-- 依赖范围:test包下依赖该设置 -->            <scope>test</scope>        </dependency>       </dependencies>      </project>Maven会自动访问中央仓库下载依赖的jar包。
2.编写测试类,使用 Assert断言我们的结果是否为hellomavenpackage com.cad.maven; import static org.junit.Assert.*;import org.junit.Test; public class TestHelloWorld{    @Test    public void testsayHello(){        HelloWorld hw=new HelloWorld();        String result=hm.sayHello("maven");        AssertEquals("hellomaven",result);    }}
3.运行mvn clean test命令  会显示测试报告,通过了多少、失败了多少、跳过了多少等

这里写图片描述

项目打包

将我们的项目打包,包可以指定很多类型,后面我们会详细介绍。不指定的话默认是jar包,我们使用mvn package命令进行打包,会在target目录下有我们打好的jar包  

这里写图片描述

这里写图片描述

项目安装

我们其他的Maven项目如何使用我们的项目呢,我们可以使用install命令将我们的jar包安装到本地仓库,然后在其他项目中通过gav来引用。

mvn install

这里写图片描述

使用Archetype生成项目骨架

Maven项目有一些约定,在根目录放pom.xml文件,src/main/java中放源码等等。如果我们每次创建Maven项目都需要自己来创建这个骨架的话,估计会烦的要命。Maven为我们提供了Archetype来帮助我们快速构建项目骨架。

我们在使用mvn archetype:generate命令生成项目骨架,Maven会有很多骨架供我们选择,也会提供一个默认的骨架,我们直接回车,然后会让我们输入groupid、artifactid、version、package等,然后就可以生成完整的项目骨架,极其方便。

这里写图片描述

常用Maven命令总结

Maven的命令要在根在目录中去执行

Mvn compile: 编译命令Mvn clean:   清除命令,清除已经编译好的class文件,具体说清除的是target目录中的文件Mvn test:    测试命令,该命令会将test目录中的源码进行编译Mvn package: 打包命令Mvn install: 安装命令,会将打好的包,安装到本地仓库命令是可以组合的:    Mvn clean compile:先清空再编译    mvn clean test命令:先执行clean,再执行test,通常应用于测试环节    mvn clean package:先执行clean,再执行package,将项目打包,通常应用于发布前        执行过程:            清理————清空环境            编译————编译源码            测试————测试源码            打包————将编译的非测试类打包     mvn clean install:先执行clean,再执行install,将项目打包,通常应用于发布前        执行过程:            清理————清空环境            编译————编译源码            测试————测试源码            打包————将编译的非测试类打包            部署————将打好的包发布到资源仓库中

M2Eclipse的使用

我们的项目一般都是在IDE中进行编写,Eclipse有一款强大的Maven插件M2Eclipse。新版的Eclipse中都自带这款插件。

1.我们在Eclipse中创建一个Maven项目,选择new->Maven Project,选择默认的工作空间即可,点击next 

这里写图片描述

2.这一步会让我们选择骨架,我们选择quickstart

这里写图片描述

3.输入坐标 

这里写图片描述

4.点击finish,完成创建

执行Maven命令

我们在项目上右键run as会出现一些常用的Maven命令。

这里写图片描述

如果这些命令不能满足我们要求,我们需要别的命令怎么办呢?我们只需要选择Maven build就可以自己输入Maven命令,在这里输入Maven命令不需要加mvn。点击run即可运行

这里写图片描述

Maven坐标

Maven的很强大的一个功能就是管理项目依赖,为了能自动化的精确获取到项目依赖,Maven就必须为其唯一标识,Maven通过坐标来构建唯一标识。

平面几何中,使用(x,y)坐标来表示平面中的任何一个点。Maven中拥有数量巨大的构件,就是jar、war等文件,Maven自己创建了一种坐标规则,只要我们指定争取的坐标,Maven就会到中央仓库中下载这些构建,Maven的中央仓库中包含了世界上流行的大部分构件。

坐标详解

我们来看一组坐标      <groupId>com.cad.maven</groupId>     <artifactId>HelloWorld</artifactId>     <version>0.0.1</version>     <packaging>jar</packaging> 
  • groupId:组织名称。项目属于哪个组。例如Spring-core,Spring-context都是属于SpringFramework组的。

  • artifactId:项目名称。

  • version:定义当前项目的版本

  • packaging:定义项目的打包方式。例如jar、war。不指定默认为jar

Maven依赖管理

根元素project下的dependencies可以包含一个或多个 dependency元素,以声明一个或多个项目依赖。
每个依赖可以包含以下元素。

<groupId>:依赖组织名称    <artifactId>:依赖项目名称<version>:版本 <scope>:依赖范围<type>:依赖类型,对应于项目坐标定义的packing。默认值为jar<optional>:标记依赖是否可选 <exclusions>:用来排除传递性依赖 

依赖范围

我们在前面的测试例子中,依赖的JUnit设置了一个<scope>为test,为什么这么设置呢?这就涉及到依赖范围的概念。 首先我们需要知道主项目代码在编译时需要使用一套classpath,编译主代码需要使用jar包,该jar包就以依赖的方式被引入到classpath中。Maven在编译和执行测试代码时,会使用另一套classpath,然后例如junit包等也会被引入这个classpath中。最后,实际运行项目时,又会使用另一套classpath,一些spring等jar包需要在该classpath中,而junit等就不需要。 

依赖范围就是用来控制依赖应该在何时存在,例如junit包只需要在测试时存在,项目正式运行时就不需要了。

Maven有以下几种依赖范围

  • compile:没有指定,默认使用该依赖范围。使用此依赖范围,对于主代码、测试、运行时都会被引入各自的classpath。例子是spring-core,在主代码、测试、运行时都需要这个依赖。

  • test:测试依赖范围。使用此依赖范围的Maven依赖,只会被测试classpath引入。例子是JUnit,只有在测试时需要。

  • provided:使用此依赖范围的Maven依赖,会被主代码、测试等classpath引入,在运行时无效。例子是servlet-api,编译主代码和测试时需要,但在运行时由于容器会提供,所以可能会出现冲突,就不需要Maven再引入依赖。

  • runtime:运行时依赖范围。使用此依赖范围的Maven依赖,只有项目运行时会引入依赖。例子是JDBC驱动,在编译主代码时无效,只有测试运行还有运行时需要引入。

这里写图片描述

依赖传递

什么是依赖传递呢?

我们说一个简单的例子,例如我们的B项目依赖C项目,我们的A项目依赖于B项目,C项目的很多依赖在A项目中也需要,Maven有依赖传递机制,我们A项目既然依赖了B项目,就不需要考虑B项目依赖了什么,也不用担心使用不了C项目的依赖,再重复定义依赖,Maven会解析各个直接依赖的pom文件,将那些间接依赖引入到当前项目中。

依赖传递范围

依赖范围会对依赖传递产生影响。

我们上面的例子中,A项目依赖B项目,在A项目的pom文件中设置B项目的依赖范围为compile,B项目依赖C项目,在B项目的pom文件中设置c项目的依赖范围为compile。那么A项目对于C项目的传递性依赖的范围就是compile。 A项目依赖于B项目,B项目依赖于C项目。我们说A对B是第一直接依赖,B对C是第二直接依赖,A对C是间接依赖。

这里写图片描述

第一直接依赖的范围和第二直接依赖的范围决定了依赖传递范围。我们用下图来说明一下。左边第一列代表第一直接依赖的范围,上面第一行代表第二依赖的范围,中间表示传递依赖范围。

这里写图片描述

我们再来举个例子来理解该表,例如我们的A项目依赖Spring-core.jar,这是第一直接依赖,其依赖范围是test。而Spring-core.jar又依赖于commons-logging.jar,这是第二直接依赖,其依赖范围是compile。因此,对照表,即可得知,A项目是commons-logging.jar的一个范围是test的传递性依赖,也就是说在测试的时候才会将commons-logging.jar引入。我们来验证一下 
1.我们创建第一个项目FirstMaven 主代码:    package com.cad.maven.FirstMaven;    public class FirstMaven     {        public String sayHello(String name) {            return "hello"+name;        }    } 
pom文件:    <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.cad.maven</groupId>      <artifactId>FirstMaven</artifactId>      <version>0.0.1-SNAPSHOT</version>      <packaging>jar</packaging>      <name>FirstMaven</name>      <url>http://maven.apache.org</url>      <properties>        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>      </properties>      <dependencies>        <dependency>          <groupId>junit</groupId>          <artifactId>junit</artifactId>          <version>3.8.1</version>          <scope>compile</scope>        </dependency>      </dependencies>    </project>
2.创建第二个项目,SecondMaven,我们在pom文件中依赖第一个项目,依赖范围设置为compile,由于第一个项目中依赖了junit,并且范围设置为compile。所以第二个项目中也自动依赖了junit。 主代码     package com.cad.maven.SecondMaven;    import com.cad.maven.FirstMaven.FirstMaven;    class SecondMaven     {        public String sayHello(String name) {            FirstMaven fm=new FirstMaven();            return fm.sayHello(name);        }    }
pom文件 <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.cad.maven</groupId>  <artifactId>SecondMaven</artifactId>  <version>0.0.1-SNAPSHOT</version>  <packaging>jar</packaging>  <name>SecondMaven</name>  <url>http://maven.apache.org</url>  <properties>    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>  </properties>  <dependencies>    <dependency>      <groupId>com.cad.maven</groupId>      <artifactId>FirstMaven</artifactId>      <version>0.0.1-SNAPSHOT</version>      <scope>compile</scope>    </dependency>  </dependencies></project> 
3.我们创建第三个项目,ThirdMaven,依赖第二个项目,并且依赖范围设置为test     public class ThirdMaven     {        public static void main( String[] args )        {           ThirdMaven tm=new ThirdMaven();             String result=tm.sayHello();           System.out.println(result);        }        public String sayHello() {            return new SecondMaven().sayHello("maven");        }     }
pom文件     <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.cad.maven</groupId>      <artifactId>ThirdMaven</artifactId>      <version>0.0.1-SNAPSHOT</version>      <packaging>jar</packaging>      <name>ThirdMaven</name>      <url>http://maven.apache.org</url>      <properties>        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>      </properties>      <dependencies>        <dependency>          <groupId>com.cad.maven</groupId>          <artifactId>SecondMaven</artifactId>          <version>0.0.1-SNAPSHOT</version>          <scope>test</scope>        </dependency>      </dependencies>    </project>
4.这时候我们的依赖传递范围为test,就说明只在测试时能引入,所以这时候在主代码运行会报错,而测试时候运行则不会报错。
总结:    当第二依赖的范围是compile的时候,传递性依赖的范围与第一直接依赖的范围一致。    当第二直接依赖的范围是test的时候,依赖不会得以传递。    当第二依赖的范围是provided的时候,只传递第一直接依赖范围也为provided的依赖,且传递性依赖的范围同样为 provided;    当第二直接依赖的范围是runtime的时候,传递性依赖的范围与第一直接依赖的范围一致,但compile例外,此时传递的依赖范围为runtime;

依赖冲突

什么是依赖冲突呢?

    比如我们A项目依赖B项目,B项目依赖C项目。B项目依赖JUnit3.0版本,C项目依赖JUnit4.0版本,并且依赖范围都是compile。那么这时候就出现了冲突,A项目会依赖哪个呢?     Maven使用了就近原则,会使用距离A项目近的版本,所以会使用B项目的JUnit3.0版本。     如果一个pom文件中引入了两个不同版本的相同依赖,那么越靠近pom文件下面的越近。

可选依赖

什么是可选依赖呢?

    比如我们A项目依赖B项目,B项目依赖C项目,设置的依赖范围都是compile。但是我们的A项目根本就不需要C项目,这时候就可以设置C项目的可选依赖,有个 <optional></optional>标签,设置为true则依赖不会传递,设置为false,依赖继续传递,这就是可选依赖。我们把C项目的可选依赖设置为true,A项目中就不会再引用C项目。 

排除依赖

我们的可选依赖可以让某个依赖不再传递,但这时就出现了一种情况,我们D依赖A项目,但是D项目也需要C,这时候C项目传递不过来,就产生了很多麻烦。这时候可以使用排除依赖,排除依赖可以把自己不需要的依赖给排除。

我们在C项目排除A项目 <dependencies>    <dependency>      <groupId>com.cad.maven</groupId>      <artifactId>SecondMaven</artifactId>      <version>0.0.1-SNAPSHOT</version>      <scope>test</scope>      //排除A项目      <exclusions>        <exclusion>            <groupId>com.cad.maven</groupId>            <artifactId>FirstMaven</artifactId>        </exclusion>      </exclusions>     </dependency>  </dependencies>

归类依赖

    我们的项目依赖spring,Spring项目分为很多个模块,例如Spring-core-4.0.jar,Spring-bean-4.0.jar等等。   等到我们项目需要更新Spring的时候,由于版本号都一样,所以我们是否可以将版本号给用一个常量存放,然后更新Spring时只需要改变常量的值即可。这样可以省去很多时间。 
<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.cad.maven</groupId>  <artifactId>ThirdMaven</artifactId>  <version>0.0.1-SNAPSHOT</version>  <packaging>jar</packaging>  <name>ThirdMaven</name>  <url>http://maven.apache.org</url>  <properties>    <springframework.version>4.5</springframework.version>  </properties>  <dependencies>      <dependency>      <groupId>org.springframework</groupId>      <artifactId>spring-core</artifactId>      <version>${springframework.version}</version>     </dependency>      <dependency>      <groupId>org.springframework</groupId>      <artifactId>spring-beans</artifactId>      <version>${springframework.version}</version>     </dependency>   </dependencies></project>

优化依赖

通过前面的学习了解,Maven会自动解析所有直接依赖和传递依赖,并且判断依赖范围,最后项目得到的的依赖被称为已解析依赖。

我们可以通过mvn dependency:list来查看当前项目已解析依赖并且显示其范围  

这里写图片描述

我们可以通过mvn dependency:tree命令来查看当前项目依赖树 

这里写图片描述

Maven仓库

Maven可以在某个统一的位置存储所有项目的依赖,这个位置就是仓库。Maven项目中只需要声明依赖的坐标,Maven会根据坐标自动寻找仓库中的依赖,并使用他们。而我们的项目也可以安装部署到仓库中,使其他项目使用。

根据Maven坐标定义每个构建在仓库中唯一存储路径大致为:groupId/artifactId/version/artifactId-version.packaging。

仓库的分类

Maven仓库分为本地仓库和远程仓库。Maven根据坐标寻找依赖时,会先到本地仓库查找,如果有则直接使用,如果没有则到远程仓库查找,如果查找到则下载到本地仓库使用,没有查找到就报错。

远程仓库又分为中央仓库和私服还有其他公开的远程仓库。私服是一种特殊的远程仓库,我们可以在公司内部部署一个私服,这样每个员工使用依赖时就不用每个人都去中央仓库下载,而是去局域网的私服下载,还可以把公司内部的项目放在私服上,供所有人使用,节省了带宽和时间。

本地仓库

默认情况下,本地仓库的地址是用户目录下的.m2/repository/ ,但是我们可以编辑settings.xml文件来自己设置目录,前面我们有讲过,就不再多说。

中央仓库

默认的中央仓库地址是http://repo1.maven.org/maven2。中央仓库包含了世界上大部分开源依赖。

私服

私服架设在局域网内,供局域网内的用户使用。Maven需要下载依赖时,先请求私服,如果私服没有,则从外部的远程仓库下载,自己还可以向私服上上传自己的项目,供局域网使用。

私服有很多优点。

  • 节省自己带宽:大量对于外部仓库的访问会占用很多带宽。
  • 没网的时候也可以使用
  • 可以部署自己的项目

后面我们会详细介绍私服的搭建。

配置其他远程仓库

有时候我们默认的中央仓库无法满足我们的需求,可能项目需要的依赖存在于其他公开的远程仓库。例如JBoss Maven仓库,可以在我们的pom文件中配置该仓库。

配置JBoss Maven仓库   <repositories>    <repository>        <!--唯一id-->        <id>jboss</id>        <name>JBoss Repository</name>        <!--仓库的url地址-->        <url>http://repository.jboss.com/maven2/</url>         <!--开启发布版本下载支持-->        <releases>            <enabled>true</enabled>        </releases>        <!--关闭快照版本下载支持-->        <snapshots>            <enabled>false</enabled>        </snapshots>        <!--使用默认布局-->        <layout>default</layout>    </repository>  </repositories>

快照版本

Maven中任何一个项目依赖都需要有唯一的版本。例如1.0, 2.3.1 , 4.2-SNAPSHOT.
其中1.0,2.3.1都是发布版本,4.2-SNAPSHOT是快照版本。

为什么要区别发布版本和快照版本呢?

A开发一个项目的B模块,C开发D模块,D模块依赖B模块。A需要经常将自己的B模块更新供D使用。Maven每个坐标都是唯一的,A将自己的项目发布为2.1版本供C调用,那么有一些微小的改动,就需要发布2.2,2.3等版本,造成版本号的滥用。Maven的快照就是解决这个问题,A只需要将自己的版本设置为2.1-SNAPSHOT,发布到私服中,Maven会自动为项目打上时间戳,有了时间戳,Maven就能找到该项目的最新版本,C开发D模块时,D模块会自动的检查模块B的2.1-SNAPSHOT是否是最新,发现有更新便下载。

快照版本应该只在组织内部或模块依赖间使用,真正发布还是要发布正式版。

Maven生命周期

什么是生命周期?

Maven还没出现之前,项目构建的生命周期就存在。程序员每天都对项目进行清理、编译、测试、打包等工作,各个公司都一样,有的是手工完成,有的可以编写自动化脚本完成,虽然过程可能有点细微的不一样,但非常类似。Maven的生命周期就是对所有的构建过程进行抽象和统一,总结了一套高度完善、易扩展的生命周期,包含了清理、编译、测试、打包、部署等几乎所有的构建步骤。Maven的生命周期是抽象的,不做任何事情,都由各种插件完成。简单的说,生命周期可以理解为构建步骤的集合。

Maven有3套生命周期,clean、default、site。生命周期包括多个阶段,这些阶段有一定的顺序,并且执行后面的阶段前面的阶段也会自动执行。例如clean的生命周期包含pre-clean、clean、post-clean,当用户执行pre-clean命令时,只有pre-clean执行,当用户执行clean时,会执行pre-clean和clean命令,当用户执行post-clean命令时,会执行三个命令。

clean生命周期

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

default生命周期

validate generate-sources process-sources generate-resources process-resources 复制并处理资源文件,至目标目录,准备打包。 compile 编译主项目的源代码。 process-classes generate-test-sources process-test-sources generate-test-resources process-test-resources 复制并处理资源文件,至目标测试目录。 test-compile 编译测试源代码。 process-test-classes test 使用合适的单元测试框架运行测试。这些测试代码不会被打包或部署。 prepare-package package 接受编译好的代码,打包成可发布的格式,如 JAR 。 pre-integration-test integration-test post-integration-test verify install 将包安装至本地仓库,以让其它项目依赖。 deploy 将最终的包复制到远程的仓库,以让其它开发人员与项目共享。  

site生命周期

site生命周期的目的是建立发布项目站点,上面有项目的各种信息。

pre-site 执行一些需要在生成站点文档之前完成的工作 site 生成项目的站点文档 post-site 执行一些需要在生成站点文档之后完成的工作,并且为部署做准备 site-deploy 将生成的站点文档部署到特定的服务器上  

Maven插件

我们前面说Maven的核心仅仅定义了抽象的生命周期,具体的任务是由插件完成的。为了让用户不用自己配置插件就能构建Maven项目,Maven在核心为一些主要的生命周期绑定了很多插件,当用户执行生命周期阶段时,对应的插件就会起作用。

自定义绑定插件

 <build>        <plugins>            <!--指定编译插件用的jdk版本-->            <plugin>                <groupId>org.apache.maven.plugins</groupId>                <artifactId>maven-compiler-plugin</artifactId>                <configuration>                    <source>1.7</source>                    <target>1.7</target>                    <encoding>utf-8</encoding>                </configuration>            </plugin>        </plugins>  </build>

插件的使用是Maven中很难的一个地方,如果需要深入可以去参考文档。

Maven聚合

在大型项目中,可能会有很多模块,在Maven中可以将这些模块给聚合成一个项目。

1.我们首先需要创建一个空的Maven项目,来去聚合其他模块,该模块的packaging必须为pom  
2.通过<module>标签聚合其他项目,该被聚合的项目路径必须放在聚合项目pom文件的同一路径下     <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.cad.MavenWeb</groupId>      <artifactId>WebDemo</artifactId>      <version>0.0.1-SNAPSHOT</version>      <packaging>pom</packaging>      <modules>        <module>WebServlet</module>        <module>WebService</module>      </modules>    </project> 

这里写图片描述

我们可以直接使用Eclipse图形化创建聚合项目1.先创建一个Maven项目,将packaging改为pom2.新建模块即可

这里写图片描述

这里写图片描述

3.我们执行一下编译命令,Maven会首先解析聚合模块的pom,分析需要构建的模块,然后根据顺序构建各个模块 

这里写图片描述

Maven继承

Maven的继承,实质上指的是pom文件的继承,我们在前面的例子中会发现,pom文件中有的时候会有很多重复的内容,例如重复引入插件,重复指定gav坐标等。

1.我们首先创建一个父项目,父项目的打包方式必须为pom  由于父项目只是为了让子   项目继承pom文件,所以打包方式选为pom。

这里写图片描述

2.使用Eclipse创建子项目,只需要指定父项目的坐标即可 

这里写图片描述

我们看一下子项目的pom文件 ,可以看到用一个parent标签引入了父项目<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>  <parent>    <groupId>com.cad.maven</groupId>    <artifactId>ParentProject</artifactId>    <version>0.0.1-SNAPSHOT</version>  </parent>  <groupId>com.cad.maven</groupId>  <artifactId>ChildProject</artifactId>  <version>0.0.1-SNAPSHOT</version></project>

依赖继承

子项目会默认继承父项目中的依赖。但是如果某个模块继承父项目,根本不需要这些依赖,怎么办?

Maven提供的<dependencyManagement> 标签既能让子模块继承父模块的依赖,也能保证子模块依赖使用的灵活性。<dependencyManagement> 下的依赖声明并不会引入实际的依赖,只是管理依赖的版本。 
例如 ,我们的父模块使用这个标签,这样即不会为父模块添加依赖,也不会为继承的子模块添加依赖  <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.cad.maven</groupId>  <artifactId>ParentProject</artifactId>  <version>0.0.1-SNAPSHOT</version>  <packaging>pom</packaging> <dependencyManagement>   <dependencies>    <dependency>      <groupId>junit</groupId>      <artifactId>junit</artifactId>      <version>3.8.1</version>      <scope>compile</scope>    </dependency>  </dependencies> </dependencyManagement> </project>
我们的子模块的pom文件,我们只需要给出groupId,artifactId即可,版本继承父模块的,简化了我们一些操作 <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>  <parent>    <groupId>com.cad.maven</groupId>    <artifactId>ParentProject</artifactId>    <version>0.0.1-SNAPSHOT</version>  </parent>  <groupId>com.cad.maven</groupId>  <artifactId>ChildProject</artifactId>  <version>0.0.1-SNAPSHOT</version>    <dependencies>    <dependency>      <groupId>junit</groupId>      <artifactId>junit</artifactId>    </dependency>   </dependencies>   </project>

插件继承

同样的,Maven提供了<pluginManagement>来管理插件,和依赖继承一样,在这里面配置的插件并不存在实际的插件调用,等到子pom中配置了plugin元素时,才会真正调用。

使用Nexus创建私服

1.首先我们在官网下载Nexus, http://nexus.sonatype.org/
2.修改 \nexus-3.4.0-02\etc\nexus-default.properties文件,修改访问私服的地址和端口

这里写图片描述

3.我们在\nexus-3.4.0-02\bin 目录下执行窗口cmd命令,nexus.exe/run   执行成功后,即可访问    

这里写图片描述

4.我们输入 127.0.0.1:8081\即可访问私服 

这里写图片描述

5.默认的访问Nexus都是匿名的,匿名用户仅包含一些基本的权限,要全面学习Nexus,必须以管理员身份登录。  Nexus管理员默认的账号密码是 admin/admin123

这里写图片描述

Nexus仓库和仓库组

Nexus包含了各种类型的仓库概念,包括代理仓库、宿主仓库、仓库组等,每一种仓库都提供了丰富实用的配置参数。

仓库有四种类型,group(仓库组),hosted(宿主),proxy(代理),virtual(虚拟)。仓库的格式为Maven2.仓库还有一个属性Policy(策略),表示该仓库是发布Release版本仓库还是Snapshot快照仓库。

这里写图片描述

Nexus内部的几种Maven仓库

1)maven-central:代理maven中央库,默认从https://repo1.maven.org/maven2/拉取jar 2)maven-releases:一个策略为Release的宿主类型仓库,用来部署组织内部的发布版本构件3)maven-snapshots:一个策略为Snapshot的宿主类型仓库,用来部署组织内部的快照版本构件4)maven-public:仓库分组,把上面三个仓库组合在一起对外提供服务,在本地maven基础配置settings.xml中使用。 Maven可以直接从宿主仓库下载依赖,Maven也可以从代理仓库中下载依赖,代理仓库会间接的从远程仓库下载依赖并缓存。仓库组只是一组仓库,它会转向其组内的仓库获取依赖。 

私服的配置可以自行百度,网上很多资料。

原创粉丝点击