Maven—入门知识点梳理

0、代码地址

https://gitee.com/fin_wuhongyu/bigdata2022Maven.git

1、为什么要使用Maven

1.1 Jar包添加

1. 之前添加Jar包方式
在网上找到一个Jar包,添加到libs目录下

2. 问题
之后的项目会有成百上千个Jar包,每个项目下的lib单独存在,可能会有多个Jar包被重复使用,造成磁盘空间冗余

3. 解决方式
使用本地仓库
Maven中有一个本地仓库(指电脑中的某个目录),统一存放Jar包,之后的项目只会统一依赖该目录下的Jar包,所以只会在本地仓库中保存一份

1.2 jar包获取

1. 之前获取Jar包方式
百度
csdn等论坛
官网

2. 问题
jar包不全、收费
官网需要对框架很熟悉才知道该如何下载

3. 解决方式
使用中央仓库
会有一个网址,存放规范、完整、准确,专门有人管理的jar,使用jar包的时候,直接从网上下载

1.3 jar包之间的依赖关系

1. 场景
导入Ajar包时,Ajar包依赖Bjar包,Bjar包依赖Cjar包,则使用Ajar包时,需要把A、B、Cjar包都导入,很麻烦

2.解决方式
maven导包时会将依赖的jar包一并导入,无需人工处理

1.4 jar包的冲突问题(同一个模块下的jar冲突)

1. 场景 在这里插入图片描述
三个工程相互依赖
MakeFriend工程依赖HelloFriend,HelloFriend依赖Hello

工程依赖的jar包
Hello工程依赖log4j.1.2.17.jar,而HelloFriend依赖log4j.1.2.14.jar

问题:使用MakeFriend工程时发生jar包冲突
该导入log4j.1.2.14.jar呢,还是log4j.1.2.17.jar?

2. 解决方式
maven会自动处理jar包冲突问题,使用最短路径者优先和先声明者优先(后续详讲)
MakeFriend工程会自动使用log4j.1.2.14.jar

1.5 将项目拆分成多个模块(不同模块下的jar冲突)

1. 场景
对于一个电商项目可能会拆分成用户模块、商品模块、购物车模块、支付模块、物流模块……来进行并行开发
每个模块所使用的log4j版本不一致,在测试时,单独测试没问题,但多个模块一起测试时,会报各种问题

2. 解决方式
将工程拆分,使用maven来进行多个模块jar包的统一管理
在这里插入图片描述

1.6 实现项目的分布式部署(了解)

场景
项目规模增加到一定程度,可能每个模块都需要运行在独立的服务器上(分布式部署)
这里同样需要用到Maven管理Jar包

2、Maven是什么

2.1 概述

  1. 自动构建工具
    主要用于Java平台的项目构建和依赖管理

  2. 演变过程
    Make→Ant→Maven→Gradle
    Gradle并没有在Maven上增加多少功能

2.2 项目构建(上线)步骤

  1. 清洗 Clean
    删除之前编译好的.class文件等代码清洗掉
  2. 编译 Compile
    只要编译成.class文件,java代码才会被执行
  3. 测试 Test
    可以针对项目中的关键点进行测试
  4. 报告
    打印测试结果
  5. 打包 Parkage
    java工程打成jar包
    web工程打成war包
  6. 安装 Install
    将jar包或者war包安装到本地仓库,提供给其他项目依赖使用
  7. 部署 Deploy
    部署到远程仓库或者服务器上

2.3 自动化构建

指maven可以自动帮我们完成1-5、7步,不用我们一步一步去点击

3、Maven如何使用

3.1 安装与配置

3.1.1 安装maven核心程序

检查JAVA_HOME环境变量

C:\Users\111>echo %JAVA_HOME%
D:\soft\Java\jdk1.8.0_202

安装包
在这里插入图片描述
maven是一个免安装的软件,将安装包解压到一个非中文无空格的路径下即可使用

安装路径
D:\soft\maven\apache-maven-3.5.4
在这里插入图片描述

  1. bin
    maven中的命令
  2. boot
    引导区,使用之前要去搜索一些配置环境
  3. conf
    配置文件,使用时候可以修改配置文件
  4. lib
    maven开发时所使用的jar包
    许可证、注意事项、说明书

给安装路径配环境变量
配置MAVEN_HOME
在这里插入图片描述

配置Path
在这里插入图片描述
检查是否配好

C:\Users\111>mvn -v
Apache Maven 3.5.4 (1edded0938998edf8bf061f1ceb3cfdeccf443fe; 2018-06-18T02:33:14+08:00)
Maven home: D:\soft\maven\apache-maven-3.5.4\bin\..
Java version: 1.8.0_202, vendor: Oracle Corporation, runtime: D:\soft\Java\jdk1.8.0_202\jre
Default locale: zh_CN, platform encoding: GBK
OS name: "windows 10", version: "10.0", arch: "amd64", family: "windows"

可以看到打印了maven的安装路径

Maven home: D:\soft\maven\apache-maven-3.5.4\bin\..

3.1.2 指定本地仓库

本地仓库默认位置

<!-- localRepository
   | The path to the local repository maven will use to store artifacts.
   |
   | Default: ${user.home}/.m2/repository
  <localRepository>/path/to/local/repo</localRepository>
-->

${user.home}指默认存放在当前用户家目录下
路径:C:\Users\111.m2\repository

配置
在D:\soft\maven\apache-maven-3.5.4\conf\settings.xml中添加一行

<localRepository>D:\soft\RepMaven</localRepository>

指更改本地仓库路径到:D:\soft\RepMaven

3.1.3 更换中央仓库网址

默认:中央仓库在国外
更换成阿里云的中央仓库
配置
在D:\soft\maven\apache-maven-3.5.4\conf\settings.xml中添加

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

3.1.4 更换jdk版本

默认:maven使用jdk1.4

<profile>
  <id>jdk-1.4</id>
  <activation>
    <jdk>1.4</jdk>
  </activation>
  <repositories>
    <repository>
      <id>jdk14</id>
      <name>Repository for JDK 1.4 builds</name>
      <url>http://www.myhost.com/maven/jdk14</url>
      <layout>default</layout>
      <snapshotPolicy>always</snapshotPolicy>
    </repository>
  </repositories>
</profile>

更改成和电脑一样的jdk1.8
配置
在D:\soft\maven\apache-maven-3.5.4\conf\settings.xml中添加

<profile>
    <id>jdk-1.8</id>
    <activation>
        <activeByDefault>true</activeByDefault>
        <jdk>1.8</jdk>
    </activation>
    <properties>
        <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>
</profile>

3.1.5 在idea中配置Maven

  1. 在idea登录界面进行全局配置

在这里插入图片描述

  1. 在Build,Execution,Deployment下的Build Tools中选择Maven

在这里插入图片描述

  1. 指定安装路径、配置文件和本地仓库
    在Build,Execution,Deployment下的Build Tools下的Maven中选择Importing

在这里插入图片描述
采用默认值,如果需要下载源码或者下载速度过慢,可做调整

3.2 使用,创建第一个maven工程Hello

3.2.1 在idea中使用maven,建立maven项目

  1. 建一个空项目

在这里插入图片描述

  1. 配置项目名和本地路径

在这里插入图片描述

  1. 鼠标放在最下方

在这里插入图片描述

  1. 新建maven模块

在这里插入图片描述

  1. 配置本地路径和GAV

在这里插入图片描述
目录结构
在这里插入图片描述

main目录用于存放主程序
java目录用于存放源代码文件
resources目录用于存放配置文件和资源文件
test目录用于存放测试程序

3.2.2 使用test目录进行单元测试

在pom文件中导入单元测试依赖

<!--依赖-->
<dependencies>
    <dependency>
        <groupId>junit</groupId>
        <artifactId>junit</artifactId>
        <version>4.0</version>
    </dependency>
</dependencies>
  1. 注释快捷键 ctrl+/
  2. alt + insert 可以快速生成依赖

编写主程序

package com.atguigu.maven;

public class Hello {
    public String sayHello(String name) {
        return "Hello " + name + "!";
    }
}

编写测试程序

package com.atguigu;

import com.atguigu.maven.Hello;
import org.junit.Assert;
import org.junit.Test;

public class HelloTest {
    @Test
    public void TestHello1(){
        Hello hello = new Hello();
        String result = hello.sayHello("aaaa");
        Assert.assertEquals("Hello aaaa!",result);
    }
    @Test
    public void TestHello2(){
        Hello hello = new Hello();
        hello.sayHello("bbbb");
    }
}

测试方法
在这里插入图片描述

  1. 先点击clean
  2. 再点击test、package、install、deploy……

结果
生成jar包
在这里插入图片描述

3.3 使用maven打包插件打包

maven默认打包是不带依赖的,如果需要带依赖,则需要在pom文件中加入打包插件
在pom.xml中加入如下内容

<build>
    <plugins>
        <plugin>
            <artifactId>maven-assembly-plugin</artifactId>
            <configuration>
                <descriptorRefs>
                    <descriptorRef>jar-with-dependencies</descriptorRef>
                </descriptorRefs>
            </configuration>
            <executions>
                    <execution>
                        <id>make-assembly</id>
                        <phase>package</phase>
                        <goals>
                            <goal>single</goal>
                        </goals>
                    </execution>
            </executions>
        </plugin>
    </plugins>
</build>

生成带依赖和不带依赖两种类型的jar包
在这里插入图片描述

4、Maven核心概念

4.1 pom.xml

maven主要通过pom文件来管理jar包

4.2 约定的目录结构

在这里插入图片描述
约定>配置>编码
在javaEE中,能够通过约定解决的问题就不用配置,能够通过配置解决的问题就不用编码

4.3 坐标

<?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>com.atguigu.maven</groupId>
    <artifactId>Hello</artifactId>
    <version>1.0-SNAPSHOT</version>

    <!--依赖-->
    <!--怎么从仓库中找到我需要的jar包-->
    <!--坐标2-->
    <dependencies>
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>4.0</version>
            <scope>test</scope>
        </dependency>
    </dependencies>
</project>

pom文件中一般会有两个gav,第一个是为代码完成后打入仓库的坐标,第二个是怎么从本地或者中央仓库中找到我需要的jar包

gav
(1)groupId:公司或组织的域名倒序+当前项目名称
(2)artifactId:当前项目的模块名称
(3)version:当前模块的版本

坐标1
点击install,打到本地仓库路径
在这里插入图片描述

坐标2
jar包路径
在这里插入图片描述
junit jar包

  • junit-4.0.jar
    junit jar的pom文件
  • 指定了junit jar 所依赖的jar包
    junit jar的源码
  • junit-4.0-sources.jar
    sha1文件
  • 校验核文件

D:\soft\RepMaven\junit\junit\4.0
本地仓库\groupid\artifactId\version

4.4 创建第二个工程,依赖第一个工程Hello

先将光标移动到Scratches and Consoles,再选择新建模块。
在这里插入图片描述
在这里插入图片描述
如果光标在Hello上,新生成的项目会成为Hello子模块
在这里插入图片描述
加上Hello和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">
    <modelVersion>4.0.0</modelVersion>

    <groupId>com.atguigu.maven</groupId>
    <artifactId>HelloFriend</artifactId>
    <version>1.0-SNAPSHOT</version>

    <dependencies>

        <dependency>
            <groupId>com.atguigu.maven</groupId>
            <artifactId>Hello</artifactId>
            <version>1.0-SNAPSHOT</version>
        </dependency>

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

编写主程序

package com.atguigu.maven;

public class HelloFriend {

    public String sayHelloToFriend(String name){
        Hello hello = new Hello();
        String str = hello.sayHello(name)+" I am "+this.getMyName();
        return str;
    }

    public String getMyName(){
        return "Idea";
    }
}

不用导包,因为HelloFriend和依赖的jar包Hello都是在同一个package路径下:package com.atguigu.maven;

编写测试程序

package com.atguigu.maven;

import org.junit.Test;
import static junit.framework.Assert.*;
public class HelloFriendTest {
    @Test
    public void testHelloFriend(){
        HelloFriend helloFriend = new HelloFriend();
        String results = helloFriend.sayHelloToFriend("Maven");
        System.out.println(results);
        assertEquals("Hello Maven! I am Idea",results);
    }
}

4.5 依赖管理

4.5.1 依赖的范围

导入jar包时,除了写jar包的gav,还要写jar包的,也就是jar包的使用范围,第二个工程HelloFriend导入Hello依赖的时候没有写,默认是compile

1)compile(默认就是这个范围)
a、src下的main目录下的Java代码可以访问这个范围的依赖
注意:这里是指main目录,而不是指main方法
b、test目录下的Java代码可以访问这个范围的依赖
c、部署到Tomcat服务器上运行时要放在WEB-INF的lib目录下
例:对Hello的依赖
主程序、测试程序和服务器运行时都需要用到

2)test
a、main目录下的Java代码不能访问这个范围的依赖
b、test目录下的Java代码可以访问这个范围的依赖
c、部署到Tomcat服务器上运行时不会放在WEB-INF的lib目录下
例:对junit的依赖
只是test程序需要

3)provided
a、main目录下的Java代码可以访问这个范围的依赖
b、test目录下的Java代码可以访问这个范围的依赖
c、部署到Tomcat服务器上运行时不会放在WEB-INF的lib目录下
一般用于服务器上已经存在的jar包,但是即使重复上传也不影响最终结果
例如:servlet-api在服务器上运行时,Servlet容器会提供相关API,所以部署的时候不需要

4)其他:runtime、import、system
用得少
在这里插入图片描述

4.5.2 依赖的传递性

Maven工程依赖范围对A的可见性
A Bcompile
Ctest×
Dprovided×

当A工程依赖于B、C、D工程时,只有B工程下的compile依赖,A工程才可以访问得到

4.5.3 依赖的原则

1)最短路径者优先
在这里插入图片描述
HelloFriend是MakeFriend的直接依赖,优先
2)路径相同时先声明者优先
在这里插入图片描述
按照MakeFriend的pom文件的顺序决定依赖先后顺序

<dependencies>
    <dependency>
        <groupId>com.atguigu.maven</groupId>
        <artifactId>HelloFriend</artifactId>
        <version>1.0-SNAPSHOT</version>
    </dependency>
    <dependency>
        <groupId>com.atguigu.maven</groupId>
        <artifactId>OurFriends</artifactId>
        <version>1.0-SNAPSHOT</version>
    </dependency>
<dependencies>

会选择依赖HelloFriend的log4j.1.2.14.jar

4.5.4 依赖的排除

导入Hello依赖时,默认会把Hello中的compile依赖导入
在这里插入图片描述

导入Hello时需要加入exclusions排除依赖

<dependency>
    <groupId>com.atguigu.maven</groupId>
    <artifactId>Hello</artifactId>
    <version>1.0-SNAPSHOT</version>
    <exclusions>
        <exclusion>
            <groupId>org.springframework</groupId>
            <artifactId>spring-core</artifactId>
        </exclusion>
    </exclusions>
</dependency>

在这里插入图片描述

4.5.5 统一管理jar包的版本

以后我们使用flink做项目时,会导入很多和flink相关的jar包,而且每个版本的flink都包含:flink-java、flink-json、flink-table-api-java-bridge_2.12,我们应该都导入同一个版本,而不是1.13的flink-java和1.14的flink-json
优化前

<dependencies>
    <dependency>
        <groupId>org.apache.flink</groupId>
        <artifactId>flink-java</artifactId>
        <version>1.13.0</version>
    </dependency>
    <dependency>
        <groupId>org.apache.flink</groupId>
        <artifactId>flink-json</artifactId>
        <version>1.13.0</version>
    </dependency>
    <dependency>
        <groupId>org.apache.flink</groupId>
        <artifactId>flink-table-api-java-bridge_2.12</artifactId>
        <version>1.13.0</version>
    </dependency>
<dependencies>

如果我们想要将这些jar包的版本统一升级为1.14,就得手动一个个修改呢,很麻烦。我们可以采取统一配置的方式:
优化后

<properties>
    <flink.version>1.13.0</flink.version>
</properties>

<dependencies>
    <dependency>
        <groupId>org.apache.flink</groupId>
        <artifactId>flink-java</artifactId>
        <version>${flink.version}</version>
    </dependency>
    <dependency>
        <groupId>org.apache.flink</groupId>
        <artifactId>flink-json</artifactId>
        <version>${flink.version}</version>
    </dependency>
    <dependency>
        <groupId>org.apache.flink</groupId>
        <artifactId>flink-table-api-java-bridge_2.12</artifactId>
        <version>${flink.version}</version>
    </dependency>
</dependencies>

4.5.6 仓库

4.5.6.1 分类

1)本地仓库
为当前本机电脑上的所有Maven工程服务

2)远程仓库

a)私服
架设在当前局域网环境下,为当前局域网范围内的所有Maven工程服务

b)中央仓库
架设在Internet上,为全世界所有Maven工程服务

c)中央仓库的镜像
为中央仓库分担流量,减轻中央仓库的压力
例如:阿里和网易

4.5.6.2 仓库中的文件

(1)Maven的插件
在这里插入图片描述
(2)我们自己开发的项目的模块
(3)第三方框架或工具的jar包
不管是什么样的jar包,在仓库中都是按照坐标生成目录结构,所以可以通过统一的方式查询或依赖

4.5.7 生命周期

1)Clean Lifecycle(重点)

  • 概念
    移除上一次构建生成的文件

2)Default Lifecycle(重点)

  • 概念
    构建核心工作
    生命周期内,运行任意一个生命周期,前面的生命周期都会被运行

默认生命周期

  1. 验证
    核心1:validate
  2. 资源处理
    generate-sources
    process-sources
    generate-resources
    process-resources
  3. 编译项目的源代码
    核心2:compile
  4. 测试资源处理
    process-classes
    generate-test-sources
    process-test-sources
    generate-test-resources
    process-test-resources
  5. 编译项目的源代码
    test-compile
  6. 测试
    process-test-classes
    核心3:test
  7. 接受编译好的代码,打包成可发布的格式,如JAR
    prepare-package
    核心4:package
  8. 安装资源
    pre-integration-test
    integration-test
    post-integration-test
    verify
  9. 将包安装至本地仓库,以让其它项目依赖
    核心5:install
  10. 将最终的包复制到远程的仓库,以让其它开发人员与项目共享或部署到服务器上运行
    核心6:deploy

3)Site Lifecycle

  • 概念
    生成项目报告、站点、发布站点

5、继承

5.1 为什么需要继承

之前讲依赖的传递时,说只有compile的依赖是可以被传递的,但如果是scope为test的依赖呢,我们如果想在子父模块中统一管理,则需要继承来实现

例子:有三个模块,Hello、HelloFriend、MakeFriend中,都有scope为test的依赖junit,但版本各不相同,怎么统一成4.9的版本呢
Hello

<dependency>
    <groupId>junit</groupId>
    <artifactId>junit</artifactId>
    <version>4.0</version>
    <scope>test</scope>
</dependency>

HelloFriend

<dependency>
    <groupId>junit</groupId>
    <artifactId>junit</artifactId>
    <version>4.9</version>
    <scope>test</scope>
</dependency>

MakeFriend

<dependency>
    <groupId>junit</groupId>
    <artifactId>junit</artifactId>
    <version>4.12</version>
    <scope>test</scope>
</dependency>

解决思路:我们需要使用继承机制,将各个依赖信息统一提取到父工程Parent去管理三个子模块Hello、HelloFriend、MakeFriend,而不是一个个单独手工修改

5.2. 创建父工程Parent

a、 子父模块GroupId一致
在这里插入图片描述
b、声明打包方式,为pom
含义
只做项目管理,不写任何代码
pom.xml

<packaging>pom</packaging>

之前不写packaging指打包的时候,默认打jar包
jar
如果是web工程,要改成war

<packaging>war</packaging>

c、 在子工程中引用父工程

<!--继承-->
<parent>
    <groupId>com.atguigu.maven</groupId>
    <artifactId>Parent</artifactId>
    <version>1.0-SNAPSHOT</version>
    <!--指定从当前pom.xml文件出发寻找父工程的pom.xml文件的相对路径-->
    <relativePath>../Parent/pom.xml</relativePath>
</parent>

…/Parent/pom.xml指返回上级,并进入Parent文件夹中找到pom文件

d、 在父工程中管理依赖

<!--依赖管理-->
<dependencyManagement>
    <dependencies>
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>4.0</version>
            <scope>test</scope>
        </dependency>
    </dependencies>
</dependencyManagement>

e、 子项目中重新定义依赖
删除版本号和范围,因为在父工程中已经定义过了
在子项目中重新指定需要的依赖,删除范围和版本号

<dependency>
    <groupId>junit</groupId>
    <artifactId>junit</artifactId>
</dependency>

f、结果
在这里插入图片描述

6、聚合

6.1. 为什么需要聚合

当模块较多,我们每次修改代码时,都需要先把修改的模块的代码clean、install一次,然后该模块的被依赖依赖代码也需要clean和install,很麻烦

6.2. 如何配置聚合

父模块的pom文件添加

<!--聚合-->
<modules>
    <module>../MakeFriend</module>
    <module>../HelloFriend</module>
    <module>../Hello</module>
</modules>

添加后,Parent会显示root
在这里插入图片描述

6.3 如何使用聚合

  1. 在父工程中点击clean

在这里插入图片描述
三个target同时被删除

  1. 在父工程中点击package

在这里插入图片描述
同时生成三个target
之后可以使用父工程一起clean、test、install、package……

7、Maven酷站

7.1 查询GAV

通过给定jar包的名字,版本,查询gav

7.2 使用

网址:http://mvnrepository.com/
一般情况选择使用人数最多的jar包
在这里插入图片描述
一般情况选择使用人数最多的版本
在这里插入图片描述
复制gav

<dependency>
    <groupId>junit</groupId>
    <artifactId>junit</artifactId>
    <version>4.12</version>
    <scope>test</scope>
</dependency>
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

大数据之负

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值