一、什么是 Maven?

Maven 是一个项目管理工具,它的本质是一个项目对象模型(POM),体现在配置中就是我们常见的 pom.xml 文件,而这个 pom 文件就是 Maven 的核心,它管理了整个项目的生命周期。它主要做两件事:

  • 项目构建:对项目进行编译、打包、测试、部署以及上传到私服仓库等

  • 依赖管理:Maven 诞生时就提出了一个仓库的概念,项目中用到的第三方 jar 包,我们在 pom.xml 中配置好依赖即可,Maven 会自动到它的官方中央仓库下载这个 jar 包到我们的本地仓库。

  • 中央仓库地址:https://mvnrepository.com/

二、为什么要使用 Maven?

  • 方便依赖管理:Java 发展至今,生态非常完善。我们在项目中用到什么功能,网上一搜肯定有对应的 jar 包,各种功能就导致了各种 jar 包的引入,这些 jar 包之间可能会有依赖,可能会有版本冲突。而 Maven 的诞生解决了这些问题。

  • 构建多模块项目:现在很多项目都是分了多个模块,便于开发、也便于扩展。多模块就意味着模块之间会有各种依赖,我们运行某个模块,可能这个模块依赖了别的模块。而 Maven 的一键构建项目帮我们解决了这个问题。

  • 方便移植:以前没 maven 的时代,团队协作要上传、下载一大堆 jar 包导入项目,耗时、费力。而有了 maven ,我们只需要同步一下 pom 文件即可同步 jar 包。这是 maven 解决的第三个问题。

三、怎么使用 Maven?

3.1 Maven 的安装

这个就不讲了,网上很多资料。比如:https://www.cnblogs.com/KyleXu/p/9972042.html

3.2 Maven 的配置

Maven 的配置比较简单,主要是修改 conf 文件夹下的 setting 文件。配置以下三个仓库:

本地仓库

项目依赖的 jar 包是需要下载到本地才能用的。本地仓库就是从 maven 私服或者远程仓库下载的 jar 的存储地址,默认是 当前用户名\.m2\repository ,我建议改个好记的地方,后面方便检查包有没下载到本地。打开 setting.xml 搜索 localRepository 修改成自定义的地址。

<localRepository>D:\Repository</localRepository>

配置的位置,如下图:

私服仓库

这个仓库的话,一般就是公司内部使用的啦。用来存储公司内部自己的 jar 包。打开 setting.xml 文件搜索 mirrors ,配置公司的镜像地址即可。

<mirror>
<id>nexus-repos</id>
<mirrorOf>*</mirrorOf>
<name>Team Nexus Repository</name>
<url>http://127.0.0.1:8081/nexus/content/groups/public</url>
</mirror>

远程仓库

远程仓库就是一个 maven 官方维护的,包含大量 jar 包的仓库。这个库默认是 maven 官方的,但是下载非常慢。所以业界典范阿里巴巴也推出了一个国内的镜像,我们一般把远程仓库配成阿里的镜像地址,就可以快速地下载 jar包啦。和私服仓库一样,远程仓库也是配置在 <mirrors> 标签内。

<mirror>
<id>alimaven</id>
<name>aliyun maven</name>
<url>http://maven.aliyun.com/nexus/content/groups/public/</url>
<mirrorOf>central</mirrorOf>
</mirror>

配置的位置,如下图:

有人可能问了,配置那么多个仓库。究竟 jar 从哪个下载的呀?都把我搞糊涂了,别急,我花了个流程图,它的查找顺序是这样的:本地不需要网络,优先从本地找;找不到,再去速度较高的内网私服找;然后才是速度稍低的外网远程仓库找。

3.3 Maven 的命令

常用命令

命令 含义 备注
mvn clean 清除 打包前,清空上一次的包
mvn compile 编译 将 java 代码编译成 class 文件
mvn test 测试 运行单元测试
mvn install 安装到本地 安装到本地仓库,一般是 jar 包
mvn package 打包 一般会在 target 目录下生成包,jar 或 war
mvn deploy 上传 上传到私服,需在 setting.xml 文件配置私服仓库以及账号密码

以上就是 maven 常用的命令,要注意的是:很少情况下我们只运行其中一个命令,都是组合运行的。比如打包到本地,打包前得清空原有的包吧?那组合起来就是 mvn clean + mvn install

当然,在 IDEA 中开发 maven 项目,我们并不需要手打。只需点击对应命令即可(也可以按住 ctrl 选中多个命令一起运行)

总而言之,根据自己的需求来选择打包命令。还有其他的命令请见:

创建 maven 项目

现在一般都是配合 idea 新建 maven 项目了,这个命令用得很少,但我们还是得知道一下:生成 maven 项目的原理是,依赖一个插件 maven-archetype-plugin,然后这个插件自带一些 archetype 模版,也可以说成项目的骨架。其中:-DgroupId-DartifactId填写自己想好的项目坐标,一般 -DgroupId是公司名的翻转,比如 com.google-DartifactId 就是项目的名称了。最重要的是-DarchetypeArtifactId,他指定了创建的骨架。

mvn archetype:generate -DgroupId=com.nasus -DartifactId=maven-test -DarchetypeArtifactId=maven-archetype-quickstart -DinteractiveMode=false

点进去,只有 src文件夹和 pom.xml文件:src 是最重要的目录,代码和测试用例以及资源都是放在这里的,对于 maven 项目而言,pom.xml 也是必不可少的。

idea 打开的项目结构是这样的:

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/maven-v4_0_0.xsd"> <!--声明项目描述符遵循哪一个 POM 模型版本,上面的 xsd 规范定义了这个版本,默认就行,不需要修改,不可删除-->
<modelVersion>4.0.0</modelVersion> <!--团体唯一标识符-->
<groupId>com.nasus</groupId> <!--项目唯一标识符定位这个包-->
<artifactId>maven-test</artifactId> <!--打包类型-->
<packaging>jar</packaging> <!--打包版本-->
<version>1.0-SNAPSHOT</version> <!--包名-->
<name>maven-test</name> <!--不用管,删掉也行-->
<url>http://maven.apache.org</url> <!--项目需要依赖的 jar 包-->
<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>3.8.1</version>
<scope>test</scope>
</dependency>
</dependencies>
</project>

由于篇幅原因,这里就不详细讲具体的 pom.xml 标签了,详细介绍请看:

项目打包到本地仓库

由于项目是 java 项目,在打包前,我们要在 pom.xml 中配置项目的 JDK 版本以及 maven 插件版本,在 <dependencies> 标签前加入项目属性配置,完整配置如下:

    <!--项目属性,在 <dependencies> 前加-->
<properties>
<!-- JDK编译版本 -->
<java.version>1.8</java.version>
<!-- 项目编码 -->
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<!-- JDK编译版本 -->
<maven.compiler.source>1.8</maven.compiler.source>
<maven.compiler.target>1.8</maven.compiler.target>
<maven.compiler.compilerVersion>1.8</maven.compiler.compilerVersion>
</properties>
<!--项目需要依赖的 jar 包-->
<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>3.8.1</version>
<scope>test</scope>
</dependency>
</dependencies>

选择命令,这里我选了 clean、compile、package

点击绿色执行按钮,在 target 目录下生成 maven-test-1.0.SNAPSHOT.jar:

跳过单元测试

在开发中,我们经常需要本地测试,而这时我们是不需要跑单元测试的。所以,我们可以跳过单元测试:选中 test,点击红框按钮即可。

手动打 jar 包到本地仓库

手动打 jar 包的应用场景是:开发公司旧项目,当找不到依赖的 jar 源码,依赖的 jar 又没有上传到仓库,只有在同事电脑的本地仓库有一个 jar 包时,我们可以直接运行这条命令把 jar 包打到我们电脑本地仓库,愉快的使用起来。

mvn install:install-file -Dfile=jar包的路径 -DgroupId=gruopId中的内容 -DartifactId=actifactId的内容 -Dversion=version的内容 -Dpackaging=jar

四、maven 依赖管理

maven 通过 pom.xml 来进行依赖管理,我们用它来描述项目的依赖属性。可以把它看作是 maven 项目的地图,它描述了 jar 包的坐标、版本以及依赖关系等。如果不确定你想要引入 jar 的坐标怎么写,可以上 maven 中央仓库查询:

4.1 maven 坐标

maven 的第三方依赖都在 <dependencies>标签内定义,该标签下的 <dependency> 包裹的内容就是一个 jar 的坐标,如下 pom 就引入了 junitcglib 两个 jar 。下面就说一下每个坐标的标签都代表什么。

<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.11</version>
<scope>test</scope>
</dependency> <dependency>
<groupId>cglib</groupId>
<artifactId>cglib</artifactId>
<version>3.3.0</version>
</dependency>
</dependencies>
  • dependencies

在 dependencies 标签中,添加项目需要的 jar 所对应的 maven 坐标。

  • dependency

一个 dependency 标签表示一个坐标,也就是一个 jar,在 pom 中引入一个 jar 可以这样写:

<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.11</version>
<scope>test</scope>
</dependency>
  • groupId

公司、团体、个人开发者的唯一标识符,maven 约束它以创建这个项目的组织名称的逆向域名开头,比如开发者的域名是 nasus.com 那他的唯一标识符就是 com.nasus

<!--团体唯一标识符-->
<groupId>com.nasus</groupId>
  • artifactId

项目唯一标识符,一个组织可能有多个项目,为了方便 maven 引入,maven 约定以项目名称命名该标识符,比如我开发的 maven-test 项目。

<!--项目唯一标识符-->
<artifactId>maven-test</artifactId>
  • version

项目的版本。一个项目,可能会有多个版本。如果是正在开发的项目,我们可以给版本号加上一个 SNAPSHOT,表示这是一个快照版本。

什么是快照?

对于版本,如果 maven 以前下载过指定的版本文件,比如说 maven-test:1.0maven 将不会再从仓库下载新的可用的 1.0 文件。若要下载更新的代码,maven-test 的版本需要升到 1.1

快照是一种特殊的版本,指定了某个当前的开发进度的副本。不同于常规的版本,maven 每次构建都会在远程仓库中检查新的快照。我们自己的模块依赖了同事开发的模块,正常来说,同事会每次发布更新代码的快照到仓库中。

新建项目的默认版本号就是快照版,比如上面用 maven 命令新建的 maven-test 项目:

4.2 依赖范围

  • scope

maven 项目不同的阶段引入到 classpath 中的依赖是不同的,例如,编译时,maven 会将与编译相关的依赖引入 classpath 中,测试时,maven 会将测试相关的的依赖引入到 classpath 中,运行时,maven 会将与运行相关的依赖引入 classpath 中,而依赖范围就是用来控制依赖于这三种 classpath 的关系。 如下图所示:

scope 表示依赖的范围,它有 compile(编译阶段)、test(测试阶段)、provided(供应阶段)、runtime(运行阶段)、system(系统阶段)、import(导入阶段) 六个可选值。其中 compile 是默认的。systemimport 用得少,不详细讲。

不同依赖的适用范围不一样,举几个最典型的栗子:

范围 编译有效 测试有效 运行时有效 打包有效 示例
compile spring-core
test junit
provided javax.servlet-api
runtime JDBC驱动
  • compile: 编译依赖范围。如果没有指定,就会默认使用该依赖范围。使用此依赖范围的 Maven 依赖,对于编译、供应、测试、运行四种 classpath 都有效。比如 spring-core

  • provided: 已提供依赖范围。使用此依赖范围的 Maven 依赖,对于 编译和测试 classpath 有效,但在运行时无效。典型的例子是 servlet-api 编译和测试项目的时候需要该依赖,但在运行项目的时候,由于容器已经提供,就不需要 maven 重复地引入一遍:

<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
<version>3.1.0</version>
<scope>provided</scope>
</dependency>
  • test: 单元测试依赖范围,只在测试的时候生效,所以可以设置它的 scope 为 test,这样,当项目打包发布时,单元测试的依赖就不会跟着发布。比如:
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.11</version>
<scope>test</scope>
</dependency>
  • runtime: 运行时依赖范围。对于测试和运行 classpath 有效,但在编译主代码时无效。典型的例子是 JDBC 驱动实现,项目主代码的编译只需要 JDK 提供的 JDBC 接口,只有在执行测试或者运行项目的时候才需要实现上述接口的具体 JDBC 驱动。所以,我们使用 JDBD 驱动时,可以定义成以下样例:
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>8.0.12</version>
<scope>runtime</csope>
</dependency>

4.3 排除依赖

如下 xml,原来的定义中已引入 commons-net 依赖,而 hermes-ftp 中又依赖了 commons-net,为避免版本冲突,我们可以排除 hermes-ftp 中的 commons-net 依赖。

<dependency>
<groupId>commons-net</groupId>
<artifactId>commons-net</artifactId>
<version>3.6</version>
</dependency>
<dependency>
<groupId>com.nasus.greece.jupiter</groupId>
<artifactId>hermes-ftp</artifactId>
<version>1.1.0-SNAPSHOT</version>
<!--排除 commons-net 依赖-->
<exclusions>
<exclusion>
<artifactId>commons-net</artifactId>
<groupId>commons-net</groupId>
</exclusion>
</exclusions>
</dependency>

4.4 依赖传递

假设有如下项目关系:WebMavenDemo 项目依赖 JavaMavenService1JavaMavenService1 项目依赖 JavaMavenService2

pom.xml 文件配置好依赖关系后,必须首先 mvn install 后,依赖的 jar 包才能使用。比如:

  • WebMavenDemopom.xml 文件想能编译通过,JavaMavenService1 必须 mvn install
  • JavaMavenServicepom.xml 文件想能编译通过,JavaMavenService2 必须 mvn install

传递性:

假设我们现在 JavaMavenService2 增加 spring-core ,那就会发现WebMavenDemoJavaMavenService1 也会自动的增加了这个jar包,这就是依赖的传递性。

注意:非 compile 范围的依赖是不能传递的。

  • 来源:cnblogs.com/hzg110/p/6936101.html

4.5 统一管理依赖版本

在上面介绍 pom 文件时,我们讲过 properties 标签,它还有一个作用就是限定依赖的 jar 包版本,它常用在父项目中指定版本号,那么子项目用到该包就避免了版本不一致造成的依赖冲突,它的写法是这样的:

五、build 配置

maven 打 war 包时,可能需要一些额外的配置,请参看以下 xml 文件:

<build>
  <!-- 项目的名字 -->
  <finalName>maven-test</finalName>
  <!-- 描述项目中资源的位置 -->
  <resources>
    <!-- 自定义资源1 -->
    <resource>
      <!-- 资源目录 -->
      <directory>src/main/java</directory>
      <!-- 包括哪些文件参与打包 -->
      <includes>
        <include>**/*.xml</include>
      </includes>
      <!-- 排除哪些文件不参与打包 -->
      <excludes>
        <exclude>**/*.txt</exclude>
          <exclude>**/*.doc</exclude>
      </excludes>
    </resource>
  </resources>
  <!-- 设置构建时候的插件 -->
  <plugins>
    <plugin>
      <groupId>org.apache.maven.plugins</groupId>
      <artifactId>maven-compiler-plugin</artifactId>
      <version>2.1</version>
      <configuration>
        <!-- 源代码编译版本 -->
        <source>1.8</source>
        <!-- 目标平台编译版本 -->
        <target>1.8</target>
      </configuration>
    </plugin>
    <!-- 资源插件(资源的插件) -->
    <plugin>
      <groupId>org.apache.maven.plugins</groupId>
      <artifactId>maven-resources-plugin</artifactId>
      <version>2.1</version>
      <executions>
        <execution>
          <phase>compile</phase>
        </execution>
      </executions>
      <configuration>
        <encoding>UTF-8</encoding>
      </configuration>
    </plugin>
    <!-- war插件(将项目打成war包) -->
    <plugin>
      <groupId>org.apache.maven.plugins</groupId>
      <artifactId>maven-war-plugin</artifactId>
      <version>2.1</version>
      <configuration>
        <!-- war包名字 -->
        <warName>maven-test</warName>
      </configuration>
    </plugin>
  </plugins>
</build>

六、使用 idea 搭建 maven 聚合工程

这个网上很多资料,不讲了。留个链接。

最后

如果看到这里,喜欢这篇文章的话,请转发、点赞。微信搜索「一个优秀的废人」,欢迎关注。

回复「1024」送你一套完整的 java、python、c++、go、前端、linux、算法、大数据、人工智能、小程序以及英语教程。

回复「电子书」送你 50+ 本 java 电子书。

Maven 基础(一) | 使用 Maven 的正确姿势的更多相关文章

  1. Maven基础学习(一)—Maven入门

    一.概述      Maven是一个项目管理工具,它包含了一个项目对象模型(Project Object Model),一组标准集合,一个项目生命周期(Project Lifecycle),一个依赖管 ...

  2. Maven基础配置—本地Maven配置

    1.下载客户端 通过http://maven.apache.org/download.cgi#下载Maven本地客户端. 我下载的是apache-maven-3.2.5-bin.zip,在D盘解压. ...

  3. (一)Maven基础及第一个Maven工程

    一.Maven介绍 ANT/Maven/gradle是一个项目管理工具,它包含了一项目对象模型(Project Object Model),一组标准集合,一个项目生命周期(Project Lifecy ...

  4. Maven基础

    Maven基础 maven核心内容:依赖管理. Maven是Apache组织的开源项目,是项目构建工具.用来管理jar包之间的相互依赖关系 Maven是一个项目构建和管理的工具,提供了帮助管理,构建, ...

  5. 搭建 Maven ---基础入门

    这篇随笔从最基础的控制台  搭建maven讲,后面再升入的讲解IDEA搭建Maven. 一,Maven是什么?作用是什么? Maven是一个项目管理工具,它包含了一个项目对象模型 (Project O ...

  6. maven基础学习-为什么要用maven,帮助解决了什么问题,怎么解决的,希望以后学习每个知识点都可以这样问下自己

    maven基础学习 第1章 Maven介绍 1.1 什么是Maven 1.1.1 什么是Maven Maven 的正确发音是[ˈmevən],而不是"马瘟"以及其他什么瘟.Mave ...

  7. maven基础知识

    1.maven基础知识 1.1maven坐标 maven坐标通常用冒号作为分割符来书写,像这样的格式:groupId:artifactId:packaging:version.项目包含了junit3. ...

  8. Maven基础知识和环境搭建

    基本概念和生命周期 Maven是现在流行的构建自动化工具,提供了软件构建过程中全生命周期的管理. 基础目录结构 基础目录结构如下: 根目录:存放pom.xml 和所有的子目录 ${basedir}/s ...

  9. [转载]maven基础入门

    用 Maven 做项目构建 本文转载自:https://www.ibm.com/developerworks/cn/java/j-lo-maven/ 本文将介绍基于 Apache Maven 3 的项 ...

随机推荐

  1. 深入java面向对象一:==和equals详解

    本文从多篇博客笔记融合而来,系转载,非原创,参考: 1.  http://www.cnblogs.com/e241138/archive/2012/09/16/2687981.html 2.  htt ...

  2. ThinkPHP 模版中的内置标签

    内置标签就是模版引擎提供的一组可以完成控制.循环和判断功能的类似HTML语法的标签.   一.判断比较:   1.if标签进行条件判断 //if语句的完整格式 <if condition=&qu ...

  3. linux 阻塞 open 作为对 EBUSY 的替代

    当设备不可存取, 返回一个错误常常是最合理的方法, 但是有些情况用户可能更愿意等待 设备. 例如, 如果一个数据通讯通道既用于规律地预期地传送报告(使用 crontab), 也用于根据 用户的需要偶尔 ...

  4. JS 手札记

    addEventListener中的事件如果移除(removeEventListener)的话不能在事件中执行bind(this)否则会移除无效! // selectCurrent() // copy ...

  5. Codeforces Round #587 C. White Sheet(思维+计算几何)

    传送门 •题意 先给一个白矩阵,再两个黑矩阵 如果两个黑矩阵能把白矩阵包含,则输出NO 否则输出YES •思路 计算几何题还是思维题呢? 想起了上初中高中做几何求面积的题 这个就类似于那样 包含的话分 ...

  6. Centos6.5_x64-GitLab搭建私有GitHub

              GitLab,是一个利用 Ruby on Rails 开发的开源应用程序,实现一个自托管的Git项目仓库,可通过Web界面进行访问公开的或者私人项目. 它拥有与GitHub类似的功 ...

  7. Python3 安装pylint 及与PyCharm关联

    使用如下命令: pip3 install pylint 安装完后可以看到在你的python3的目录底下的Scripts目录下有pylint.exe了 然后就可以使用pylint 评估你的代码了,如: ...

  8. python元祖(tuple)

    # 列表:有序,元素可以被修改 # 列表 # list # li = [111,22,33,44] # 元组:元素不可被修改,不能被增加或者删除 # ps: # tuple # tu = (11,22 ...

  9. JavaScript | 值传递、引用传递的区别

    值传递 JavaScript值传递的数据类型:字符串(String).数字(Number).布尔(Boolean).空(Null).未定义(Undefined), 这五种数据类型是按值访问的,因为可以 ...

  10. flask修改数据库字段的类型和长度

    flask修改数据库字段的类型和长度 ​ 在将models中的字段的db.String(256)修改为db.String(1024)后,执行migrate和upgrade操作后,发现数据库并没有更新, ...