maven

一、maven 是什么

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

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

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

 

二、什么是 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

三、什么是依赖管理?

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

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

  (一)依赖范围

依赖范围就是用来控制依赖应该在何时存在,例如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文件,将那些间接依赖引入到当前项目中。

 

(三)依赖传递范围

总结:
    当第二依赖的范围是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的安装和配置

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 怎样创建 Java 项目?

使用Archetype生成项目骨架

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

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

 

七、maven 怎样创建 parent 项目?

  <parent>
    <groupId>com.cad.maven</groupId>
    <artifactId>ParentProject</artifactId>
    <version>0.0.1-SNAPSHOT</version>
  </parent>

  

八、maven 如何创建 Java web 项目?

 

九、什么是 maven module?  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> 

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

 

十、maven module 与 project 有什么区别?

1.maven project和module相当于父子关系。

2.当新建的项目中不存在父子关系时使用project。

3.当项目中存在父子关系时用project做父工程,module做子工程,module工程必须有父工程。

 十一、maven 如何编译源代码?maven 如何测试项目?maven 怎样打包?

常用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,将项目打包,通常应用于发布前
        执行过程:
            清理————清空环境
            编译————编译源码
            测试————测试源码
            打包————将编译的非测试类打包
            部署————将打好的包发布到资源仓库中

十二、maven 怎样安装到本地仓库?

 

1、在Maven安装的目录的conf下有settings.xml文件,这是Maven的全局配置文件 我们可以在这儿配置本地仓库的地址

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

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

 

十三、maven 编译时,如何跳过测试代码?

  目前用到的方法如下,本文会持续更新~

方法一:pom文件添加如下配置:

         <plugins>

            <plugin>

                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-surefire-plugin</artifactId>
                <configuration>
                  <skip>true</skip>
                </configuration>

            </plugin>

      </plugins>

 

 

方法二:

-DskipTests,不执行测试用例,但编译测试用例类生成相应的class文件至target/test-classes下。

-Dmaven.test.skip=true,不执行测试用例,也不编译测试用例类。

在eclipse中run as执行,如:clean install -Dmaven.test.skip=true

 

maven下载源码指令:

mvn dependency:sources

mvn dependency:resolve -Dclassifier=javadoc

命令使用方法:首先进入到相应的pom.xml目录中,然后执行以上命令: 
第一个命令是尝试下载在pom.xml中依赖的文件的源代码。
第二个命令:是尝试下载对应的javadocs
但是有可能一些文件没有源代码或者javadocs

 

maven 通过 Tomcat 插件,如何运行 Java web 项目?

maven 怎样发布到 Tomcat?

maven 如何产生 site?

 

posted @ 2018-08-13 00:07  跃小云  阅读(268)  评论(0编辑  收藏  举报