Skip to content

Maven

1.什么是Maven

官方网站 https://maven.apache.org/

Maven是一款服务于Java平台的自动化构建工具,它可以帮助我们更方便的对项目进行构建、管理项目jar包

,包括: bulid 项目,切换 jar 版本,添加 jar, 删除 jar 包等

1.1 Maven下载和安装

  1. 第 1 种方式: 直接使用 idea 自带的 Maven
  2. 第 2 种方式: 自己下载 Maven 软件, 安装、配置并使用.
  3. 下载地址 https://archive.apache.org/dist/maven/maven-3/

image-20230212102531499

安装步骤

  1. 直接解 maven 安装到指定目录

image-20230212102720733

  1. 目录结构说明

image-20230212102730712

  1. maven 使用需要依赖 jdk ,因此事先要保证安装了 jdk1.8 以上
  2. 配置环境变量 MAVEN_HOME

image-20230212102833657

  1. 配置环境变量 PATH, 增加 Maven 的路径, (如果有多个 Maven 的 Path, 可以上移, 提高优先级)

image-20230212102913687

  1. 测试是否安装 maven 成功.

image-20230212102954093

1.2 Maven 工作原理图

image-20230212103046299

  1. 在 maven 项目的 pom.xml, 可以配置项目依赖的 jar(指定坐标即可)
  2. maven 根据配置, 到中央仓库/私服 去获取 jar,下载到本地仓库
  3. maven 项目, 会引用本地仓库的 jar ,完成项目开发
  4. 在 maven 项目构建生命周期中,每个阶段的执行都有相应的插件完成
  5. 各个插件执行过程中,会附带输出内容,比如 jar/war/xml/源码
  6. 程序员可以使用 maven 默认的插件,也可以自定义插件,完成定制任务.

Maven 项目统一的开发结构分析:

image-20230212103231029

2.Maven 相关概念

2.1仓库:存储项目需要的 jar 包

image-20230212103318509

  1. 几乎所有的 jar 包都保存在中央仓库 . 地址: https://mvnrepository.com/

image-20230212103412177

  1. 本地仓库:在使用 maven 时,会将需要的 jar 下载到本地,保存在指定目录下,称为本地仓库(如图)

image-20230212103438524

image-20230212103455961

  1. 私服: 开发团队搭建的存储资源的仓库,可以个性化仓库(比如只供团队使用的 jar), 同时提升下载速度
  2. 我们个人开发时,可以直接从中央仓库下,如果想提升下载速度,可以设置镜像仓库

2.2 坐标

作用: 资源的唯一标识,定位 Maven 仓库中资源的位置

坐标构成

  1. groupld(组织 id): 定义当前 Maven 项目隶属组织名称(例如∶com.spring)
  2. artifactId(项目 ID): 定义当前 Maven 项目名称
  3. version(版本号): 定义当前项目版本号
  4. 如何获取 jar 坐标
  • 比如 mysql jar

image-20230212103758939

3.Maven构建指令

3.1 完成编译

  1. 编译指令
shell
mvn compile

image-20230212104811222

  1. 编程成功,会自动创建 target 目录,并生成对应的.class 文件(如图)
  2. 细节说明: 第一次速度慢,需要下载相关 jar,后面就快了.

image-20230212104959190

3.2完成测试

  1. 测试指令
shell
mvn test
  1. 测试指令执行完毕,会生成 Test 源文件的 class , 还会输出测试结果
  2. 细节说明: 第一次速度慢,需要完成一些初始化工作,后面就快了

image-20230212105454644

image-20230212105606804

3.3 完成打包

  1. 打包指令
shell
mvn package
  1. 打包后,在 target 目录生成对应的 打包文件 jar

image-20230212105932494

3.4 完成安装

  1. 执行 install 指令,能完成 maven 项目的安装,会把打包得到的 jar, 提交到本地仓库

image-20230212110218645

  1. 当把 maven-project01-1.0-SNAPSHOT.jar 提交到本地仓库后,该 jar 也可以被其他 maven 项目使用了,非常方便

3.5完成清理

  1. 执行如下指令,完成 maven 项目的清理,会清除生成的 target 目录

    shell
    mvn clean

3.6小结 Maven 构建指令

● 说明: Maven 构建命令使用 mvn 开头,后面添加功能参数,可以一次执行多个命令,使 用空格分隔

shell
mvn compile #编译
mvn clean #清理
mvn test #测试
mvn package #打包
mvn install #安装

image-20230212110754112

4.IDEA创建 Maven Web 工程

  1. 需求说明/图解

image-20230212111418347

image-20230212111525956

image-20230212111611291

image-20230212111727971

  1. 创建成功的 maven web 项目结构

    image-20230212111843339

  2. 创建的 pom.xml

xml
<?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>

  <!--
  1. 前面三个 groupId , artifactid 和 version 就是该 maven 项目坐标
  2. package 是打包方式,默认是 jar , 这里是 war(因为这是 web 项目)
  -->
  <groupId>com.llp</groupId>
  <artifactId>maven-javaWeb</artifactId>
  <version>1.0-SNAPSHOT</version>
  <packaging>war</packaging>

  <name>maven-javaWeb Maven Webapp</name>
  <url>http://www.example.com</url>

  <!--maven项目的属性,根据实际情况可以修改-->
  <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>
    <!--创建maven项目默认引入的jar-->
    <dependency>
      <groupId>junit</groupId>
      <artifactId>junit</artifactId>
      <version>4.11</version>
      <scope>test</scope>
    </dependency>
  </dependencies>

  <!--默认引入的 maven 插件, 前面说过 mvn 的各种指令 compile/install/test 等都是由插件完成的 -->
  <build>
    <finalName>maven-javaWeb</finalName>
    <pluginManagement><!-- lock down plugins versions to avoid using Maven defaults (may be moved to parent pom) -->
      <plugins>
        <plugin>
          <artifactId>maven-clean-plugin</artifactId>
          <version>3.1.0</version>
        </plugin>
        <!-- see http://maven.apache.org/ref/current/maven-core/default-bindings.html#Plugin_bindings_for_war_packaging -->
        <plugin>
          <artifactId>maven-resources-plugin</artifactId>
          <version>3.0.2</version>
        </plugin>
        <plugin>
          <artifactId>maven-compiler-plugin</artifactId>
          <version>3.8.0</version>
        </plugin>
        <plugin>
          <artifactId>maven-surefire-plugin</artifactId>
          <version>2.22.1</version>
        </plugin>
        <plugin>
          <artifactId>maven-war-plugin</artifactId>
          <version>3.2.2</version>
        </plugin>
        <plugin>
          <artifactId>maven-install-plugin</artifactId>
          <version>2.5.2</version>
        </plugin>
        <plugin>
          <artifactId>maven-deploy-plugin</artifactId>
          <version>2.8.2</version>
        </plugin>
      </plugins>
    </pluginManagement>
  </build>
</project>
  1. 配置 Tomcat 服务器&运行
  • 为 maven web 项目配置 tomcat

image-20230212112909732

image-20230212112953171

image-20230212113047445

image-20230212113124447

image-20230212113326184

5.Maven依赖管理

5.1依赖配置

一句话: 依赖指当前项目运行需要的 jar,一个项目可以设置多个依赖

● 依赖的举例

xml
<!--
1. 这里就是引入项目需要的 jar 包, 类似传统的 import jar 的作用
2. 在 dependencies 标签内,可以指定多个需要依赖的 jar/导入的 jar
3. 引入的 jar 包需要一个完整的 jar 包坐标,从 mvn 仓库查询即可得到-->
    <dependencies>
        <!-- 引入的一个具体的依赖 jar, 包括一个完整的依赖坐标 -->
        <dependency>
            <!-- 依赖的 gruopid: 组织名 -->
            <groupId>junit</groupId>
            <!-- 依赖的项目名 -->
            <artifactId>junit</artifactId>
            <!-- 依赖的版本 -->
            <version>4.12</version>
            <scope>test</scope>
        </dependency>
    </dependencies>

5.2依赖传递

直接依赖: 在当前项目中通过依赖配置建立的依赖关系

比如,在项目的pom.xml文件中,引入mysql8.0.27,这时我们就说项目直接依赖了mysql8.0.27

xml
<!--引入mysql依赖-->
<dependency>
    <groupId>mysql</groupId>
    <artifactId>mysql-connector-java</artifactId>
    <version>8.0.27</version>
</dependency>

5.3间接依赖

间接依赖: 当前项目直接依赖资源(比如 m1), 而 m1 又依赖资源(m2),我们就说 当前项目间接依赖资源(m2)

比如,项目A引入了一个mysql8.0.27的jar,而项目B有引入了A项目的jar,这样就形成了间接依赖

image-20230212114357293

5.4依赖冲突

路径优先

  1. 路径优先∶当依赖中出现相同的资源时,层级越深,优先级越低,层级越浅,优先级越高
  2. 示意图说明:

image-20230212114435859

  1. 项目 A 依赖情况
  • 如果 1 度资源有 junit 4.1 , 而 2 度资源有 junit4.2
  • 根据路径优先原则, 项目 A 生效的是 junit4.1

image-20230212115532807

声明优先

  1. 声明优先∶当资源在相同层级被依赖时,配置顺序靠前的覆盖配置顺序靠后的
  2. 示意图说明:

image-20230212115628592

image-20230212120009045

特殊优先

  1. 特殊优先∶当同级配置了相同资源的不同版本,后配置的覆盖先配置的(要尽量避免这种没有意义的冲突)

5.5可选依赖

可选依赖:可选依赖指对外隐藏当前所依赖的资源 - 不透明

xml
<dependency>
        <groupId>junit</groupId>
        <artifactId>junit</artifactId>
        <version>4.10</version>
        <!--
        optional:默认是false,表示不隐藏
        optional:设置为true,表示隐藏,其他模块就没办法使用
        -->
        <optional>true</optional>
        <scope>test</scope>
    </dependency>

image-20230212120908996

5.6 排除依赖

一句话: 排除依赖指主动断开依赖的资源, 被排除的资源无需指定版本- 不需要

image-20230212121135687

xml
<dependencies>
    <dependency>
        <groupId>com.llp</groupId>
        <artifactId>maven-project-2</artifactId>
        <version>1.0-SNAPSHOT</version>
        <!--
        1.指定要排除的依赖
        2.可以排除多个,在exclusions下添加多个exclusion即可
        -->
        <exclusions>
            <exclusion>
                <groupId>mysql</groupId>
                <artifactId>mysql-connector-java</artifactId>
            </exclusion>
        </exclusions>
    </dependency>
</dependencies>

image-20230212121400837

5.7可选依赖和排除依赖区别

一句话: 隐藏依赖是不让其他项目来引用(我不给), 排除依赖是主动不要引入的某个资源(我不要)

5.8依赖范围

一句话: 依赖的 jar 默认情况可以在任何地方使用, 通过 scope 标签设定其作用范围

● 作用范围说明

  1. 主程序范围有效(src/main 文件夹范围内)
  2. 测试程序范围有效(src/test 文件夹范围内)
  3. 是否参与打包(package 指令范围内)
  4. compile(默认,在主程序、测试代码、打包都有效)

● 作用范围一览图

image-20230212121709499

  1. 某个引入的 jar 包作用范围是程序员根据,业务的实际需要来设置的,不要认为是固定的。
  2. 比如 log4j jar 包,在主程序,测试代码,打包都是需要的, 因此作用范围应当设置为complie
  3. junit 只是测试代码需要,因此作用范围设置为 test 合适,但是如果程序员认为在主程序和打包就是要 junit, 仍然可以设置为默认 compile
  4. 比如 servlet-api 是 tomcat 自己带的,当把程序打包放到生产环境时,用生产环境tomcat 的 servlet-api 即可,所以设置为 provided 合适,这样就放在 servlet-api 版本冲突.
  5. 比如 jdbc, 是第三方的 jar , 打包放在生产环境,就应当在自己的包提供 jdbc 驱动包,否则程序会因为少驱动包,运行失败

6.Maven 项目构建生命周期

一句话: Maven 构建生命周期描述的是一次构建过程经历了多少个事件

image-20230212122541709

6.1生命周期的 3 大阶段

  1. clean∶清理工作

image-20230212131322297

  1. default∶核心工作,例如编译,测试,打包,部署等

image-20230212131410611

  1. site∶产生报告,发布站点等

image-20230212131427256

6.2 生命周期是分阶段执行的

一句话: 项目构建生命周期分很多阶段,并不是每次都完整执行,而是根据用户的要求 来执行的【比如你执行 compile, 那么就执行到 complie 这个阶段,如果你执行 install, 则会 执行 compile->test->package->install】

7.maven 插件

7.1介绍

  1. 插件与生命周期内的某个阶段绑定,在执行到对应生命周期时, 由对应插件来完成任务/功能.
  2. maven 插件很多,先看一张图:

image-20230212131800070

  1. 通过插件可以自定义其他功能

7.2 文档

文档: http://maven.apache.org/plugins/index.html

7.3自定义插件-应用实例

需求: 在 pom.xml 加入自定义插件,能够在对 maven_D 项目 打包时,能输出主程序和测试程序的源码

● 完成步骤

  1. 当前 package 只会得到项目的 jar

image-20230212133927056

  1. 修改 D:\java_projects\maven_D\pom.xml, 加入 maven 插件 并配置(注意: 加入自定义插件后,可能会爆红,重启项目即可.)
xml
<!-- 在build时, 自定义插件 -->
<build>
    <plugins>
        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-source-plugin</artifactId>
            <version>2.2.1</version>
            <executions>
                <execution>
                    <goals>
                        <!-- 对主程序输出源码打包 -->
                        <goal>jar</goal>
                        <!-- 对测试程序输出源码打包 -->
                        <goal>test-jar</goal>
                    </goals>
                    <!-- 指定执行阶段 -->
                    <phase>generate-test-resources</phase>
                </execution>
            </executions>
        </plugin>
    </plugins>
</build>
  1. 观察一下 maven 项目管理器

image-20230212134020584

  1. 再次执行 maven-D 的 intall 操作, 会得到两个新的 jar ,分别包含了主程序和测试程序的源码。(测试时,需要保证 src/main/... 和 src/test/... 两个目录下有 java 源代码,否则不会生成源码 jar)

image-20230212134052734

image-20230212134057747

7.4maven 插件-maven 构建生命周期关系图

image-20230212134151511

  1. 在 maven 项目构建生命周期中,每个阶段的执行都有相应的插件完成
  2. 各个插件执行过程中,会附带输出内容,比如 jar/war/xml/源码
  3. 程序员可以使用 maven 默认的插件,也可以自定义插件,完成定制任务.
  4. 自定义插件引入成功, 是可以看到