Maven从入门到精通,小白也能快速上手

Posted 陈皮的JavaLib

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Maven从入门到精通,小白也能快速上手相关的知识,希望对你有一定的参考价值。

我是陈皮,一个在互联网 Coding 的 ITer,微信搜索「陈皮的JavaLib」第一时间阅读最新文章,回复【资料】,即可获得我精心整理的技术资料,电子书籍,一线大厂面试资料和优秀简历模板。

1 Maven 简介


Maven 是 Apache 组织下的一个纯 Java 开发的开源项目。基于项目对象模型(POM)概念,Maven 是一个项目管理工具,提供对 Java 项目进行构建、打包、部署、依赖管理以及项目信息管理等功能。当然,Maven 也可用于构建和管理其他语言项目,例如 C#,Ruby,Scala 等。

我们平时开发一个项目,做的事情就是搭建项目框架,写代码,单元测试,编译构建,生成文档,打包部署等等工作。其实程序员更应该将精力用在写代码上,而其他比较固定的繁琐步骤不应该我们每次去处理。使用 Maven 就可以将这些步骤进行自动化管理,节省了开发时间,提高开发效率。

Maven 有一个生命周期,当我们运行一些 Maven 命令的时候,Maven 会执行一系列的有序的步骤,例如清除,编译,测试,打包等等,直到到达指定的生命周期。

Maven 官网地址:http://maven.apache.org/


2 构建工具


Maven 不是唯一的项目构建,管理工具,下面介绍主要的三个构建工具,推荐使用 Maven 和 Gradle。

  • Ant:比较早的 Java 构建工具,对工程构建过程控制比较灵活,但是使用的 xml 脚本格式文件比较大,逐渐很少人使用了。
  • Maven:改善了 Ant 的缺点,可以从网上下载依赖,也是使用 xml 格式配置文件,更加专注依赖管理,目前大多数公司使用。
  • Gradle:结合 Ant 的灵活和 Maven 生命周期管理的优点,不再使用 xml 格式配置文件,而是使用 DSL 脚本格式,使用 groovy 语言编写,更加灵活,是比较新型的构建工具,目前在一些初创互联网公司使用比较多,以后可能会成为主流。

3 Maven 安装与配置


因为 Maven 是用 Java 开发的,所以首先要安装 JDK,推荐使用 JDK1.8 以上版本。以下是我使用的 JDK 版本。

C:\\Users\\Administrator>java -version
java version "1.8.0_144"
Java(TM) SE Runtime Environment (build 1.8.0_144-b01)
Java HotSpot(TM) 64-Bit Server VM (build 25.144-b01, mixed mode)

下载 Maven 安装包,可以在官网下载,目前最高版本是 3.8.1:http://maven.apache.org/download.cgi

在这里插入图片描述
其他历史版本下载地址:https://archive.apache.org/dist/maven/maven-3/,目前我使用的是 3.6.3 版本。

在这里插入图片描述

下载完后解压到你想解压的目录(最好不要使用中文和空格的目录)

在这里插入图片描述

然后在系统环境变量中配置 MAVEN_HOME,值是你解压到的 Maven 目录;再将 bin 目录配置到 path 环境变量中。

MAVEN_HOME:D:\\devTools\\apache-maven-3.6.3(解压所在目录)
PATH:%MAVEN_HOME%\\bin

在这里插入图片描述


在这里插入图片描述

验证是否安装成功,打开cmd窗口,输入 mvn -v,出现如下信息则安装成功。

C:\\Users\\Administrator>mvn -v
Apache Maven 3.6.3 (cecedd343002696d0abb50b32b541b8a6ba2883f)
Maven home: D:\\devTools\\apache-maven-3.6.3\\bin\\..
Java version: 1.8.0_144, vendor: Oracle Corporation, runtime: C:\\Program Files\\Java\\jdk1.8.0_144\\jre
Default locale: zh_CN, platform encoding: GBK
OS name: "windows 10", version: "10.0", arch: "amd64", family: "windows"

修改 Maven 配置(可选),主要是修改资源下载地址,因为默认下载地址是 Google,下载速度会很慢,可以修改国内的例如阿里云的。其次是修改下载资源的存放位置,如果不修改,默认是 c 盘用户目录下的 .m2 路径中。

Maven 配置文件在解压后的 conf 目录下,settings.xml 文件。修改资源下载地址为阿里云,以及修改资源库存放位置。

<!-- 资源库存放位置 -->
<localRepository>D:\\MavenRepository</localRepository>

<!-- 资源下载地址 -->
<mirror>
   <id>alimaven</id>
   <name>aliyun maven</name>
   <url>http://maven.aliyun.com/nexus/content/groups/public/</url>
   <mirrorOf>central</mirrorOf>        
</mirror>

在这里插入图片描述

在这里插入图片描述


4 IDEA,Eclipse 配置 Maven


4.1 IDEA 配置 Maven

IDEA 配置 Maven,有两种方式,一种是针对本项目,只对此项目有效;一种是全局配置,针对所有新项目生效,一般我们会配置全局性的。

针对单项目配置

路径:File | Settings | Build, Execution, Deployment | Build Tools | Maven。

在这里插入图片描述

全局配置

路径:File | Other Settings | Settings for New Projects | Build, Execution, Deployment | Build Tools | Maven。

在这里插入图片描述


4.2 Eclipse 配置 Maven

路径:Window | Preferences | Maven | User Settings

在这里插入图片描述


5 依赖管理


Maven 其中一个核心特性就是依赖管理。我们开发的项目基本会使用外部依赖,或者我们需要处理多模块项目的模块之间的依赖,这些依赖关系非常复杂,管理起来比较困难。使用 Maven 管理依赖能大大降低难度。

Maven 对于依赖管理一个特点是可传递性依赖发现,比如我们项目依赖于 A,A 又依赖于 B,如果我们手动添加的话,需要将 A 和 B 两个依赖都下载引入项目。而使用 Maven 来构建项目的话,我们只需要显示引入依赖 A,Maven 会通过读取项目文件(pom.xml),找出它们项目之间的依赖关系,将 A 和 B 都引入进来。

Maven 使用坐标管理依赖,坐标包含三个标识信息,通过坐标可以唯一标识一个依赖。任何基于 Maven 构建的项目都必须定义这三个信息,包括我们自己开发的项目。可以在 https://mvnrepository.com/ 查找依赖。

  • group:定义当前项目所属组织或公司的唯一标识,一般为组织或者公司名称域名倒写(也可以是域名倒写+项目名),例如 com.alibaba
  • artifactId:项目的唯一 ID,一般是实际项目名称或者实际项目的一个模块名称(如果项目比较大,会划分多模块,例如 spring-core,spring-bean),例如 fastjson
  • version:项目的版本号,例如 1.2.76
<dependency>
    <groupId>com.alibaba</groupId>
    <artifactId>fastjson</artifactId>
    <version>1.2.76</version>
</dependency>

Maven 对于依赖管理有以下基本原则:

  • 依赖管理:可传递性依赖发现,Maven 会通过读取项目文件(pom.xml),找出项目之间的依赖关系,然后将需要的所有依赖引入进来。
  • 依赖调节:当一个依赖的不同版本在依赖树里的深度是一样时,第一个被声明的依赖将会被使用。
  • 依赖范围:可以指定依赖的使用范围,即项目在构建过程每个阶段所包含的依赖。
  • 依赖排除:任何可传递的依赖都可以通过 “exclusion” 元素被排除在外。例如,A 依赖 B, B 依赖 C,A 可以标记 C 为 “被排除的”。
  • 依赖可选:任何可传递的依赖可以通过 “optional” 元素 标记为可选的。例如,A 依赖 B, B 依赖 C。B 可以标记 C 为可选的, 这样 A 就可以不再使用 C。

依赖的范围可选项如下:

  • compile:编译范围,也是默认的依赖范围。使用此范围的依赖,在编译,测试,运行时三种 classpath 都有效。
  • provided:已提供范围。使用此范围的依赖,在编译,测试 classpath 中有效,在运行时 classpath 无效。例如 servlet-api 依赖,编译和测试需要此依赖,但是在运行时不需要,因为容器已经提供了。
  • test:测试范围。该范围表明相关依赖只在测试编译阶段和执行阶段。
  • runtime:运行时范围。在测试和运行时有效,编译期无效。例如 JDBC 驱动实现,在项目编译时只需要 JDK 提供的 JDBC 接口,只有在测试和运行时才真正需要 JDBC 接口的实现类,即 具体的 JDBC 驱动。
  • system:系统范围。此依赖范围和 provided 一样,但是它必须显示通过 systemPath 指定依赖文件的路径。这种依赖不是由 Maven 中央仓库解析的,一般是本地的某个路径下的依赖。
  • optional:表明依赖是可选的。
  • exclusions:用来排除传递性依赖。

这里讲下依赖范围为 system 的情况,项目如何引入外部依赖。首先将下载好的外部依赖,放入到项目已经创建好的文件夹里(例如 libs)。

在这里插入图片描述

在项目的 pom.xml 文件中添加依赖

<dependency>
  <groupId>com.alibaba</groupId>  <!-- 可以自定义 -->
  <artifactId>fastjson</artifactId>   <!--可以自定义-->
  <version>1.2.75</version>
  <scope>system</scope>
  <systemPath>${basedir}\\libs\\fastjson-1.2.75.jar</systemPath>
</dependency>

6 Maven 仓库


基于 Maven 构建的项目,项目需要的依赖首先会在本地仓库中查找,如果没有找到则会从远程仓库下载到本地仓库。如果这两者都没有找到,Maven 就会报错。

远程仓库可以分为中央仓库其他公共库以及私服

  • 中央仓库是 Maven 默认的远程仓库。地址:https://repo.maven.apache.org
  • 其他公共库一般是中央仓库的镜像加速库,因为中央仓库在国外,在国内下载会比较慢,所以有些组织或者公司会创建其他公共库供大家使用,例如阿里云仓库。
  • 私服一般是在局域网内设立的一个私有的仓库服务,供内部开发人员使用。它代理了外部远程仓库,内部用户下载依赖的时候会先到私服上查找,如果没有才从外部远程仓库下载,并缓存在私服。能节省带宽和加快下载速度,并且公司内部的依赖也能放在私服上供公司其他人下载使用。

每个用户在自己电脑上会有个本地仓库,存放所有下载过的依赖包,Windows 环境下,位置一般在用户目录的 .m2/repository 目录下。


7 Maven 项目结构


基于约定大于配置的原则,Maven 制定了一套标准的项目目录结构,规定了哪些文件需要放在哪些目录下,解决了在不同 IDE 开发工具中带来的项目目录结构不一致的问题。

  • ${basedir}:根目录,pom.xml 文件以及项目所有的子目录
  • ${basedir}/src/main/java:项目的 java 源代码
  • ${basedir}/src/main/resources:项目的资源文件,例如 application.yml,xml 文件等
  • ${basedir}/src/test/java:存放项目的 java 测试源代码
  • ${basedir}/src/test/resources:存放项目测试要用的资源文件
  • ${basedir}/target:编译打包输出目录
  • ${basedir}/target/classes:编译输出目录
  • ${basedir}/target/test-classes:测试编译输出目录

在这里插入图片描述

8 插件机制


Maven 可以添加插件,插件其实就是一些 jar 文件,执行 Maven 命令时,真正完成功能的就是插件。例如项目使用 Tomcat 服务器,我们可以引入一些 Tomcat 相关的插件。使用 springboot 框架,可以用引入 spring-boot 相关的 maven 插件。

<build>
  <plugins>
    <plugin>
      <groupId>org.springframework.boot</groupId>
      <artifactId>spring-boot-maven-plugin</artifactId>
    </plugin>
  </plugins>
</build>

比较常用的插件是 Maven 编译插件,可以设置项目使用的 JDK 版本时通过编译插件指定。

<build>
  <plugins>
    <plugin>
      <groupId>org.apache.maven.plugins</groupId>
      <artifactId>maven-compiler-plugin</artifactId>
      <version>3.8.1</version>
    </plugin>
    <configuration>
	  <source>1.8</source>
	  <target>1.8</target>
    </configuration>
  </plugins>
</build>

9 Maven 命令


Maven 提供了许多命令,来帮助构建,管理项目。不过现在许多 IDE 开发工具提供了将这些命令图形化的功能,只要点击相应的按钮也可执行相应的命令。

Maven 的命令格式:mvn [plugin-name]:[goal-name],即执行 plugin-name 插件的 goal-name 目标。

  • mvn -version:显示 Maven 版本信息
  • mvn clean:清理项目编译产生的临时文件,一般是模块下的 target 目录
  • mvn compile:编译源代码
  • mvn package:打包项目,一般会在模块下的 target 目录下生成 jar 或者 war 文件
  • mvn test:执行测试用例
  • mvn install:打包项目的 jar 或者 war 到本地仓库,供其他模块使用
  • mvn deploy:打包项目的 jar 或者 war 到远程仓库,供其他人员下载使用
  • mvn site:生成项目相关信息的网站
  • mvn eclipse:eclipse:将项目转化为 eclipse 项目
  • mvn dependency:tree:打印项目的整个依赖树
  • mvn archetype:generate:创建普通 maven 项目
  • mvn tomcat7:run:在 tomcat 容器中运行 web 项目
  • mvn jetty:run:在 jetty 容器中运行 web 项目

Maven 命令可以带参数,例如 mvn package -Dmaven.test.skip=true 会在打包的时候跳过单元测试。

Maven 有以下三个标准的生命周期

  • clean:清理项目产生的临时文件
  • default(也叫 build):关于项目构建,打包,部署等的处理
  • site:项目站点文档创建的处理

执行某个 maven 命令时,会先执行这个命令前的所有命令,例如执行 mvn package 生成可执行 jar,会依次执行 pre-clean,clean,…,test,package等命令。

在这里插入图片描述


10 使用 IDEA 创建简单 Maven 项目


首先通过 IDEA 工具创建一个 Maven 项目,选择 JDK,选择 Maven 模板。

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

按上述步骤一般没有 resources 目录,所以我们手动创建源文件资源目录和测试资源目录。

在这里插入图片描述
在这里插入图片描述

最终项目的目录结构如下:

在这里插入图片描述

项目根目录下有个 pom.xml 文件,一些常用标签介绍如下:

  • modelVersion:指定当前 pom 模型的版本,对于 maven2 和 maven3 来说,只能填写 4.0.0
  • groupId:定义项目的所属组或者公司,一般是公司域名的倒写
  • artifactId:项目在所属组的唯一ID
  • version:项目版本号
  • name:项目名称,可选
  • description:对项目的描述,可选
  • properties:定义一些属性变量
  • dependencies:定义项目使用到的依赖
  • packaging:项目打包的类型,默认是 jar,可选值有 jar,war,rar,ear,ejb,pom等等
  • build:与构建相关的配置,例如设置编译插件的 JDK 版本
<?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">

  <!-- 模型版本 -->
  <modelVersion>4.0.0</modelVersion>

  <groupId>com.chenpi</groupId>
  <artifactId>maven-demo</artifactId>
  <version>1.0-SNAPSHOT</version>
  <packaging>jar</packaging>
  <name>maven-demo</name>

  <properties>
    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    <maven.compiler.source>1.8</maven.compiler.source>
    <maven.compiler.target>1.8</maven.compiler.target>
  </properties>

  <dependencies>
    <dependency>
      <groupId>junit</groupId>
      <artifactId>junit</artifactId>
      <version>4.11</version>
      <scope>test</scope>
    </dependency>
  </dependencies>
  
  <build>
  </build>
</project>

在剪辑器的右边,有个 Maven 菜单栏,这里有 Maven 相关命令可以直接双击执行,还有插件列表,项目依赖列表。

在这里插入图片描述


11 使用 Maven 构建多模块项目


如果一个项目比较大时,会拆分成多个模块进行开发,例如一个项目的 dao,service,controller 层被拆分到不同模块中;Spring 框架中的 spring-core,spring-bean,spring-webmvc 等模块。

基于Maven 构建的项目,一般会定义一个 parent POM 作为一组子 module 的聚合 POM。在 parent POM 中使用 <modules> 标签来定义它的一组子模块。虽然在 parent POM 中不会有什么实际构建产出,但是我们可以在 parent POM 中定义一些共同构建配置,依赖等,并且可以被子模块继承。

首先创建父模块,创建一个不使用模板的 maven 项目。

在这里插入图片描述


在这里插入图片描述

然后在父模块的基础上创建子模块,直接在父模块项目右键创建子模块 maven-dao,maven-service,maven-controller。

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述


最终的项目目录结构如下所示:

在这里插入图片描述

子模块间依赖处理,因为 maven-controller 模块依赖 maven-service 模块,maven-service 模块依赖 maven-dao 模块。

我们需要在 maven-controller 模块的 pom.xml 文件中依赖 maven-service 模块;

<dependency>
  <groupId>com.chenpi</groupId>
  <artifactId>maven-service</artifactId>
  <version>1.0-SNAPSHOT</version>
</dependency>

我们需要在 maven-service 模块的 pom.xml 文件中依赖 maven-dao 模块;

<dependency>
  <groupId>com.chenpi</groupId>
  <artifactId>maven-dao</artifactId>
  <version>1.0-SNAPSHOT</version>
</dependency>

12 pom.xml 文件标签大全详解


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.0http://maven.apache.org/maven-v4_0_0.xsd">
    <!--父项目的坐标。如果项目中没有规定某个元素的值,那么父项目中的对应值即为项目的默认值。 坐标包括group ID,artifact ID和 
        version。 -->
    <parent>
        <!--被继承的父项目的构件标识符 -->
        <artifactId />
        <!--被继承的父项目的全球唯一标识符 -->
        <groupId />
        <!--被继承的父项目的版本 -->
        <version />
        <!-- 父项目的pom.xml文件的相对路径。相对路径允许你选择一个不同的路径。默认值是../pom.xml。Maven首先在构建当前项目的地方寻找父项 
            目的pom,其次在文件系统的这个位置(relativePath位置),然后在本地仓库,最后在远程仓库寻找父项目的pom。 -->
        <relativePath />
    </parent>
    <!--声明项目描述符遵循哪一个POM模型版本。模型本身的版本很少改变,虽然如此,但它仍然是必不可少的,这是为了当Maven引入了新的特性或者其他模型变更的时候,确保稳定性。 -->
    <modelVersion>4.0.0</modelVersion>
    <!--项目的全球唯一标识符,通常使用全限定的包名区分该项目和其他项目。并且构建时生成的路径也是由此生成, 如com.mycompany.app生成的相对路径为:/com/mycompany/app -->
    <groupId>asia.banseon</groupId>
    <!-- 构件的标识符,它和group ID一起唯一标识一个构件。换句话说,你不能有两个不同的项目拥有同样的artifact ID和groupID;在某个 
        特定的group ID下,artifact ID也必须是唯一的。构件是项目产生的或使用的一个东西,Maven为项目产生的构件包括:JARs,源 码,二进制发布和WARs等。 -->
    <artifactId>banseon-maven2</artifactId>
    <!--项目产生的构件类型,例如jar、war、ear、pom。插件可以创建他们自己的构件类型,所以前面列的不是全部构件类型 -->
    <packaging>jar</packaging>
    <!--项目当前版本,格式为:主版本.次版本.增量版本-限定版本号 -->
    <version>1.0-SNAPSHOT</version>
    <!--项目的名称, Maven产生的文档用 -->
    <name>banseon-maven</name>
    <!--项目主页的URL, Maven产生的文档用 -->
    <url>http://www.baidu.com/banseon</url>
    <!-- 项目的详细描述, Maven 产生的文档用。 当这个元素能够用html格式描述时(例如,CDATA中的文本会被解析器忽略,就可以包含HTML标 
        签), 不鼓励使用纯文本描述。如果你需要修改产生的web站点的索引页面,你应该修改你自己的索引页文件,而不是调整这里的文档。 -->
    <description>A maven project to study maven.</description>
    <!--描述了这个项目构建环境中的前提条件。 -->
    <prerequisites>
        <!--构建该项目或使用该插件所需要的Maven的最低版本 -->
        <maven />
    </prerequisites>
    <!--项目的问题管理系统(Bugzilla, Jira, Scarab,或任何你喜欢的问题管理系统)的名称和URL,本例为 jira -->
    <issueManagement>
        <!--问题管理系统(例如jira)的名字, -->
        <system>jira</system>
        <!--该项目使用的问题管理系统的URL -->
        <url>http://jira.baidu.com/banseon</url>
    </issueManagement>
    <!--项目持续集成信息 -->
    <ciManagement>
        <!--持续集成系统的名字,例如continuum -->
        <system />
        <!--该项目使用的持续集成系统的URL(如果持续集成系统有web接口的话)。 -->
        <url />
        <!--构建完成时,需要通知的开发者/用户的配置项。包括被通知者信息和通知条件(错误,失败,成功,警告) -->
        <notifiers>
            <!--配置一种方式,当构建中断时,以该方式通知用户/开发者 -->
            <notifier>
                <!--传送通知的途径 -->
                <type />
                <!--发生错误时是否通知 -->
                <sendOnError />
                <!--构建失败时是否通知 -->
                <sendOnFailure />
                <!--构建成功时是否通知 -->
                <sendOnSuccess />
                <!--发生警告时是否通知 -->
                <sendOnWarning />
                <!--不赞成使用。通知发送到哪里 -->
                <address />
                <!--扩展配置项 -->
                <configuration />
            </notifier>
        </notifiers>
    </ciManagement>
    <!--项目创建年份,4位数字。当产生版权信息时需要使用这个值。 -->
    <inceptionYear />
    <!--项目相关邮件列表信息 -->
    <mailingLists>
        <!--该元素描述了项目相关的所有邮件列表。自动产生的网站引用这些信息。 -->
        <mailingList>
            <!--邮件的名称 -->
            <name>Demo</name>
            <!--发送邮件的地址或链接,如果是邮件地址,创建文档时,mailto: 链接会被自动创建 -->
            <post>banseon@126.com</post>
            <!--订阅邮件的地址或链接,如果是邮件地址,创建文档时,mailto: 链接会被自动创建 -->
            <subscribe>banseon@126.com</subscribe>
            <!--取消订阅邮件的地址或链接,如果是邮件地址,创建文档时,mailto: 链接会被自动创建 -->
            <unsubscribe>banseon@126.com</unsubscribe>
            <!--你可以浏览邮件信息的URL -->
            <archive>http:/hi.baidu.com/banseon/demo/dev/</archive>
        </mailingList>
    </mailingLists>
    <!--项目开发者列表 -->
    <developers>
        <!--某个项目开发者的信息 -->
        <

以上是关于Maven从入门到精通,小白也能快速上手的主要内容,如果未能解决你的问题,请参考以下文章

Android Studio应用基础,手把手教你从入门到精通(小白学习)总结1 之 基础介绍 + intent + 常用控件

利用Python的几行代码开发一个QQ机器人!小白也能快速上手的案例

火遍全网!98页Python自动化办公教程,小白也能快速上手

火遍全网!98页Python自动化办公教程,小白也能快速上手

全网最详细中英文ChatGPT-GPT-4示例文档-类比语句智能生成从0到1快速入门——官网推荐的48种最佳应用场景(附python/node.js/curl命令源代码,小白也能学)

全网最详细中英文ChatGPT-GPT-4示例文档-个性化角色智能对话从0到1快速入门——官网推荐的48种最佳应用场景(附python/node.js/curl命令源代码,小白也能学)