目录
Maven三大功能
1.构建
- clean 清理:清除上一次的构建结果
- compile 编译:将.java文件编译成.class文件
- test测试:运行编写好的测试程序
- 报告:针对刚才的测试结果生成全面的信息
- package 打包
-
- Java工程:jar包
- Web工程:war包
- 发布:将项目发布到服务器上进行运行
2.依赖管理
- Jar包下载:使用Maven之后,Jar包的下载统一都是从Maven远程仓库中进行下载,Maven会管理所有已经上传的Jar包依赖
- Jar包依赖:Jar包本身是一个项目,项目也会依赖于其他Jar包,使用Maven只需要导入最核心的Jar包,其他依赖包会自动加载
- jar包冲突
-
- Jar包与依赖包之间版本已经搭配好,最大可能的减少了依赖版本冲突问题
- Jar包与Jar包之间依赖冲突了,那么可以通过对Jar包进行调整,从而解决依赖冲突问题
3.契约编程
- Maven项目的目录结构是已经约定好了的,这是为了让Maven的整个构建能够自动化完成,比如编译这一步,如果项目目录不约定好那么Maven也不知道应该去编译那个文件夹下的代码
- 契约编程:Maven项目的目录结构是在超级pom.xml文件中已经编写好了的,所有Maven项目都遵守这个pom.xml中约定好的结构,这是为了避免每次创建Maven项目时都需要去配置目录结构,所以这就是约定大于配置
- 开发领域趋势:约定大于配置,配置大于编码
Maven工作流程
安装
第一步:进入官网,点击下载按钮进入下载页面
第二步:点击下载windows版本Maven压缩包
解压
- Maven是绿色安装,也就是解压即安装,但是必须解压到没有空格、中文目录、特殊字符的目录,不建议放在C盘
- 要特别关注的就是conf包下的settings.xml文件,这是Maven的核心配置文件,之后我们要配置的本地仓库地址、私服仓库地址都是在此配置文件中进行配置
配置环境变量
- 执行Maven命令就需要使用到Maven包下的mvn.cmd,那么我们就需要在DOS命令窗口中进入到Maven安装目录下的bin目录下才可以执行
- 更多的时候我们希望在DOS命令窗口的任何位置都可以执行Maven命令,所以需要配置Maven的环境变量
MAVEN仓库概述
- 概述:Maven其中一个作用就是依赖管理,以前没有Maven时我们想要使用Jar包就必须在项目中的lib文件夹下放入Jar包,那么使用Maven之后就不需要我们把Jar包手动放入到项目中,而是通过依赖坐标从仓库中查找并使用依赖
- Maven寻找依赖时的顺序:本地仓库 -> 私服仓库 -> 中央仓库,如果最后中央仓库都没有就会报错,Jar包只有本地仓库中存在了才能够被使用
- 总结:所谓仓库就是用来存放所有开源三方Jar包的地方,而仓库又分为三类
-
- 本地仓库
- 私服仓库
- 中央仓库
- GAV坐标:每个Jar包的一个唯一标识,通过这个唯一标识可以找到Jar包,在下一节进行讲解
本地仓库
- 本地仓库:就是一个文件夹,专门用于存放各个本地项目中所需要的Jar包,每个Jar包都只需要从中央仓库拉取一次,后续使用时直接从本地仓库中进行获取即可,本地仓库的位置需要我们通过settings.xml进行指定
- Maven工程可以通过GAV坐标去本地仓库中进行依赖的查找,找到之后项目可直接使用仓库中的依赖
中央仓库
- 中央仓库是由Maven社区提供的仓库,也是Maven的默认仓库,在Maven安装时就已经配置好了
- 中央仓库中包含了绝大多数流行的Jar包,本地仓库的Jar包大多数都来自于中央仓库,从中央仓库拉取Jar包到本地的操作是需要联网的,并且因为中央仓库在国外所以比较慢
- 中央仓库依赖搜索地址,建议收藏:https://mvnrepository.com/
私服仓库
- 私服就是一个类似于中央仓库的Maven依赖服务器,也是用于存放Jar包的仓库
- 私服的分类
-
- 镜像仓库:由于中央仓库拉取速度较慢,国内的大厂就免费搭建了中央仓库的镜像仓库,拉取镜像仓库的速度比中央仓库速度更快,比如阿里云镜像仓库
- 公司私服仓库:公司内部在开发一些大型项目时,有可能公司内部会封装一些自己的公共Jar包供所有团队使用,但是这些Jar包又不想开源到中央仓库中,亦或者团队之间需要使用到对方的模块此时也可以通过私服仓库进行使用,这些情况下就需要搭建公司私服仓库
- 私服仓库搭建技术:Nexus
Maven配置文件
配置本地仓库
第一步:创建本地仓库文件夹
第二步:修改settings.xml配置文件中的本地仓库地址
- 注意:本地仓库地址也必须没有空格、中文、特殊字符,修改完成后记得保存
配置镜像仓库
- 默认的中央仓库服务器是在国外,而国外网站访问速度很慢,所以通常我们都会将远程仓库地址改为阿里云镜像仓库地址,提高Jar包拉取速度
- 配置方式:将以下配置复制到 settings.xml 配置文件中的 mirrors 标签中
<mirror>
<id>nexus-aliyun</id>
<name>Nexus aliyun</name>
<url>http://maven.aliyun.com/nexus/content/groups/public/</url>
<mirrorOf>central</mirrorOf>
</mirror>
配置JDK版本
- Maven的默认Java工程是使用的JDK1.5,如果使用默认的那么以后我们每次创建Maven项目都需要进行修改,所以我们需要改为我们所熟悉和常用的JDK17版本
- 配置方式:将以下配置复制到 settings.xml 配置文件中的 profiles 标签中
- 注意:记得保存配置
<profile>
<!-- 告诉maven我们用jdk17 -->
<id>jdk-17</id>
<!-- 开启JDK的使用 -->
<activation>
<activeByDefault>true</activeByDefault>
<jdk>17</jdk>
</activation>
<properties>
<!-- 配置编译器信息 -->
<maven.compiler.source>17</maven.compiler.source>
<maven.compiler.target>17</maven.compiler.target>
<maven.compiler.compilerVersion>17</maven.compiler.compilerVersion>
</properties>
</profile>
MAVEN坐标
- Maven中的坐标是项目的唯一标识,通过该坐标可以确定项目Jar包在仓库中的位置,也可以通过坐标来引入项目中所需要的三方依赖
- Maven坐标主要组成
-
- groupId:当前Maven项目隶属于组织名称,通常都是公司域名反写,例如:cn.itsouorce
- artifactId:项目或者是项目中的一个模块的名称
- version:当前Maven项目版本号,根据需求进行设定
-
-
- :快照版本,正在迭代过程中,不稳定的版本
- RELESE:表示正式版本
-
- 第一种:执行install命令将项目打成Jar包放在本地仓库中,通过坐标确定项目Jar包在仓库中的位置
pom文件解读
- pom.xml:全称是Project Object Model,又称项目对象模型,是Maven项目的核心,也是Maven项目的标识,是一个XML文件。一个Maven项目的所有Maven配置都在pom.xml中
<?xml version="1.0" encoding="UTF-8"?>
<!-- pom.xml文件的Schema约束,所有的配置都在此project根标签中进行编写 -->
<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:指定了当前pom.xml版本,从Maven2开始固定为4.0.0 -->
<modelVersion>4.0.0</modelVersion>
<!--groupId:本项目的G坐标,一般是项目所在组织或公司域名倒序,G坐标也是本项目在本地仓库中的位置-->
<groupId>cn.itsource</groupId>
<!-- artifactId:本项目的A坐标,在同一个G坐标下可以有多个项目,A坐标就是用来区别项目的唯一Id,一般都是项目名称,A坐标也是本项目在本地仓库中的位置,在G坐标之后-->
<artifactId>maven-project-01</artifactId>
<!-- version:本项目的V坐标,代表本项目的版本号,G坐标+A坐标+V坐标路径可以在项目打包之后在本地仓库中找到本项目的Jar包 -->
<version>1.0-SNAPSHOT</version>
<!-- packaging:本项目的打包方式
jar:说明本项目是一个Java项目,打包为jar包
war:说明本项目是一个web项目,打包为war包
pom:说明本项目是用来管理其他工程的,不写代码只负责管理
-->
<packaging>jar</packaging>
<!-- name:本项目名称默认是A坐标,可以不写,也可以写一个对用户更加友好的名称 -->
<name>maven-project-01</name>
<!-- url:Maven官网地址,可以不写 -->
<url>http://maven.apache.org</url>
<!-- properties:配置Maven的一些属性 -->
<properties>
<!-- 配置Maven在构建工程项目时使用UTF-8编码字符集 -->
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
<!-- dependencies:配置本项目需要引入哪些依赖们,在此标签中可以引入多个依赖 -->
<dependencies>
<!-- dependency:配置需要引入的依赖的标签,在此标签下配置需要引入依赖的GAV坐标信息 -->
<dependency>
<!-- groupId:需要引入依赖的G坐标 -->
<groupId>junit</groupId>
<!-- artifactId:需要引入依赖的A坐标 -->
<artifactId>junit</artifactId>
<!-- version:需要引入依赖的V坐标 -->
<version>3.8.1</version>
<!-- scope:配置当前依赖的范围,后续讲解 -->
<scope>test</scope>
</dependency>
</dependencies>
</project>
MAVEN常用命令
mvn compile
- 编译主体程序
- 主体程序编译结果存放在项目目录下的:target/classes
mvn test-compile
- 编译测试程序
- 测试程序编译结果存放在项目目录下的:target/test-classes
mvn clean
清除编译后的target文件
mvn package
第一种:将项目打成Jar包,打包好的项目Jar包会在target包下
mvn install
将项目打成Jar包并存放到本地仓库
deploy
将项目打成Jar包并存放到远程仓库
依赖排除
- Maven具有依赖的传递性对我们来说是非常大的一个好处,因为这样就避免我们需要去自己引入间接依赖。但是有时候我们在引入多个依赖时,简介依赖的版本不一致会导致依赖冲突,那么此时我们就需要阻断依赖
- 以Junit为例,阻断间接依赖
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.13.2</version>
<scope>test</scope>
<!--排除依赖标签,可以写多个-->
<exclusions>
<!--排除依赖标签,写具体要排除那个依赖,只需要写GA坐标即可-->
<exclusion>
<!--要排除依赖的G坐标-->
<groupId>org.hamcrest</groupId>
<!--要排除依赖的A坐标-->
<artifactId>hamcrest-core</artifactId>
</exclusion>
</exclusions>
</dependency>
MAVEN父子模块管理依赖
1.概述
- 在Java中有继承的概念,就是子类继承父类的所有方法和属性。在Maven中同样有继承的概念并且与Java一致都是单继承,本质上Maven的继承就是pom.xml配置的继承
- A工程继承了B工程,那么A工程就继承了B工程的pom.xml所有配置
- Maven继承的层级是没有限制的,大型互联网项目中层级会非常多,我们只需要按照规则去梳理层级即可
2.为什么需要继承
- 原因一:真实开发中,依赖动则几十上百个依赖,那么这些依赖的版本管理是非常复杂的,为了方便版本管理,那么可以在父工程中统一管理版本信息
- 原因二:真实开发中,一个项目会有很多个子工程,这些子工程都有自己的依赖,那么肯定会有一些重复的依赖,为了减少子工程重复导如依赖坐标信息,可以放在父工程中进行依赖抽取,让子工程通过继承的方式进行依赖的引入
- 原因三:众多依赖的版本组合是一个非常复杂的过程,因为依赖之间不同的版本会有依赖冲突问题,所以可以通过父工程确定所有依赖版本,子工程直接使用对应版本即可,SpringBoot框架就是使用了Maven继承手段进行开发简化
父模块
父模块删除src和资源文件,只留pom文件,只负责管理pom.xml,管理版本号,不负责编写代码
dependencyManagement
此标签用于在父工程中管理依赖,但是不负责引入此依赖到工程中,子工程需要使用什么依赖还是需要在自己的子工程中手动引入,只是不需要引入版本,版本来自父工程
配置自定义属性
- 父工程在真实开发中会管理众多的依赖,那么这些依赖的版本号如果都写在各自的GAV坐标中其实管理起来也颇为复杂,所以我们可以自定义属性进行管理
- properties:此标签是配置标签,我们可以在标签内自定义标签来定义属性值,此属性值可以被引用
-
- spring-web-version:此标签是自定义的,标签名称就是属性引用名称,标签的值就是版本值
- ${}:通过此方式可以引入自定义属性,大括号中的值就是自定义标签的值
<properties>
<maven.compiler.source>17</maven.compiler.source>
<maven.compiler.target>17</maven.compiler.target>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<!--统一管理版本号-->
<spring-web-version>3.1.6</spring-web-version>
<mybatis-plus-version-version>2.2.0</mybatis-plus-version-version>
</properties>
<groupId>cn.lgc</groupId>
<artifactId>maven-parent</artifactId>
<version>1.0-SNAPSHOT</version>
<!--打包方式
pom:表示当前项目是父模块,管理jar版本,不写java代码
jar:打成jar包
war:达成war包
puling:插件包
-->
<packaging>pom</packaging>
<!--管理的子模块-->
<modules>
<module>A-child</module>
<module>B-child</module>
</modules>
<!--声明式管理jar:只声明,不导入-->
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
<version>${spring-web-version}</version>
</dependency>
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus</artifactId>
<version>${mybatis-plus-version-version}</version>
</dependency>
</dependencies>
</dependencyManagement>
子模块
引入父模块
<parent>
<groupId>cn.lgc</groupId>
<artifactId>maven-parent</artifactId>
<version>1.0-SNAPSHOT</version>
</parent>
当前子模块项目名
<artifactId>A-child</artifactId>
<properties>
<maven.compiler.source>17</maven.compiler.source>
<maven.compiler.target>17</maven.compiler.target>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
引入父模块管理版本的依赖,不用写版本号
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
</dependencies>
项目部署
打包工具
- IDEA:使用IDEA可以打包Java项目为可执行的Jar包
- Maven:使用Maven打包插件可以将Java项目打包为可执行的Jar包
第一步:将父Pom中的打包插件移动到smart-campus子模块中,此插件不可全局引入,否则所有子模块都要求必须有启动类
<build>
<plugins>
<!-- maven打包插件 -->
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
第二步:将所有项目打包成不可运行的Jar包放入到本地仓库,让项目之间依赖可以找到对应的Jar包
第三步:点击smart-server子模块的package打包按钮,打包成可运行Jar包
第四步:进入到jar包所在文件夹,打开cmd,运行java -jar xxx.jar命令(original为linux系统)
仓库清理
概述
- 初始情况下,我们的本地仓库是没有任何Jar包的,第一次会联网进行下载,可能由于网络的原因,Jar包下载不完全,这些不完整的jar包都是以lastUpdated结尾
- 注意:如果依赖下载失败,Maven识别到以lastUpdated结尾的文件后就不会再重新帮你下载,需要你删除这些以lastUpdated结尾的文件,然后Maven才会再次自动下载这些Jar包,以后实际开发中如果项目引入了某Jar包刷新后依赖依然报错,那么就需要检查一下此Jar包是否下载成功
解决方案
- 有时下载依赖有可能批量下载失败,那么此时我们手动去挨着找就非常麻烦,那么我们可以定义一个脚本文件,双击即可全部清除
- 第一步:在桌面创建一个del_lastUpdated.bat文件,创建文本改后缀即可
- 第二步:右键编辑bat文件,拷贝以下命令并修改本地仓库文件夹绝对地址
set REPOSITORY_PATH=本地仓库文件夹绝对地址
rem 正在搜索...
del /s /q %REPOSITORY_PATH%\*.lastUpdated
rem 搜索完毕
pause
- 第三步:双击执行脚本,即可清除本地仓库下所有lastUpdated文件