Maven是什么?Maven的主要作用是什么?
Maven 是一款为 Java 项目构建管理、依赖管理的工具(软件),使用 Maven 可以自动化构建、测试、打包和发布项目,大大提高了开发效率和质量。
想理解Maven的概念:
我们可以从Maven的两个主要作用入手:
1:依赖管理:
例如我们项目需要第三方库(依赖),如Druid连接池、MySQL数据库驱动和Jackson等。那么我们可以将需要的依赖项的信息编写到Maven工程的配置文件,Maven软件就会自动下载并复制这些依赖项到项目中,也会自动下载依赖需要的依赖!确保依赖版本正确无冲突和依赖完整!
简单理解就是一个可以帮我们下载依赖的工具就行。
2:构建管理:
项目开发完成后,想要将项目打成.war文件,并部署到服务器中运行,使用Maven软件,我们可以通过一行构建命令(mvn package)快速项目构建和打包!节省大量时间
可以理解是一个打包工具。
Maven安装与配置:
安装:
Maven官网:Maven – Maven Releases History
推荐使用 3.6. 1
环境变量配置:
配置maven_home 和 path
如果配置在上面,是只能这个用户登录了才有这个环境变量,
配置系统变量中,就是整个电脑都能有
检测一下:
配置文件配置:
打开conf文件夹中的settting.xml文件:
1:配置本地仓库地址
设置一个自己电脑上的文件夹地址即可
2:配置国内阿里镜像
<mirror> <id>alimaven</id> <name>aliyun maven</name> <url>http://maven.aliyun.com/nexus/content/groups/public/</url><mirrorOf>central</mirrorOf> </mirror></mirrors>
3:配置JDK17项目版本构建
<profiles><profile><id>jdk-17</id><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>
本地idea配置maven:
随机点开一个项目的主菜单选择关闭项目:
找到Maven
Maven工程的概念及项目结构:
创建工程之前,我们需要知道Maven的GAVP属性:
Maven 中的 GAVP 是指 GroupId、ArtifactId、Version、Packaging 等四个属性的缩写,其中前三个是必要的,而 Packaging 属性为可选项
GAV遵循一下规则:
1) GroupID 格式:com.{公司/BU }.业务线.[子业务线],最多 4 级。
说明:{公司/BU} 例如:alibaba/taobao/tmall/aliexpress 等 BU 一级;子业务线可选。
正例:com.taobao.tddl 或 com.alibaba.sourcing.multilang com.atguigu.java
2) ArtifactID 格式:产品线名-模块名。语义不重复不遗漏,先到仓库中心去查证一下。
正例:tc-client / uic-api / tair-tool / bookstore
3) Version版本号格式推荐:主版本号.次版本号.修订号 1.0.0
1) 主版本号:当做了不兼容的 API 修改,或者增加了能改变产品方向的新功能。
2) 次版本号:当做了向下兼容的功能性新增(新增类、接口等)。
3) 修订号:修复 bug,没有修改方法签名的功能加强,保持 API 兼容性。
例如: 初始→1.0.0 修改bug → 1.0.1 功能调整 → 1.1.1等
Packaging定义规则:
指示将项目打包为什么类型的文件,idea根据packaging值,识别maven项目类型!
packaging 属性为 jar(默认值),代表普通的Java工程,打包以后是.jar结尾的文件。
packaging 属性为 war,代表Java的web工程,打包以后.war结尾的文件。
packaging 属性为 pom,代表不会打包,用来做继承的父工程。
Maven工程项目结构
重点关注这三个地方即可
pom.xml是项目的依赖
java是项目的代码
resources是项目的配置文件,也包括mybatis的配置文件
Maven依赖传递和冲突:
依赖传递指的是当一个模块或库 A 依赖于另一个模块或库 B,而 B 又依赖于模块或库 C,那么 A 会间接依赖于 C。这种依赖传递结构可以形成一个依赖树。当我们引入一个库或框架时,构建工具(如 Maven、Gradle)会自动解析和加载其所有的直接和间接依赖,确保这些依赖都可用。
简单说明
比如A 依赖于 B 依赖于 C
你直接引入A的依赖,这个时候也把BC的依赖一起引入进来了
这样做的好处就是:
减少冗余依赖的引入
减少版本冲突的可能
依赖冲突:
当直接引用或者间接引用出现了相同的jar包! 这时呢,一个项目就会出现相同的重复jar包,这就算作冲突!依赖冲突避免出现重复依赖,并且终止依赖传递!
比如
A 依赖于 B 2.2
C 依赖于 B 1.1
你这个时候同时引入A和C,就有可能会发生依赖冲突,不过Maven会帮你管理好,只会引入一个B
具体规则有两个:
-
短路优先原则(第一原则)
A—>B—>C—>D—>E—>X(version 0.0.1)
A—>F—>X(version 0.0.2)
则A依赖于X(version 0.0.2)。
-
依赖路径长度相同情况下,则“先声明优先”(第二原则)
A—>E—>X(version 0.0.1)
A—>F—>X(version 0.0.2)
在<depencies></depencies>中,先声明的,路径相同,会优先选择!
思考题:
前提:
A 1.1 -> B 1.1 -> C 1.1
F 2.2 -> B 2.2
pom声明:
F 2.2
A 1.1
B 2.2
最后我们的pom.xml文件中有:A,F,B2.2 没有C的依赖,因为导入了B2.2之后发生了依赖冲突,停止了A 1.1的依赖传递
依赖导入失败场景和解决方案
-
依赖项的版本号或配置文件中的版本号错误,或者依赖项没有正确定义,导致 Maven 下载的依赖项与实际需要的不一致,从而引发错误。
-
本地 Maven 仓库或缓存被污染或损坏,导致 Maven 无法正确地使用现有的依赖项,并且也无法重新下载!
第一种情况比较好解决,直接改版本号即可
第二种情况:清除本地 Maven 仓库缓存(lastUpdated 文件),因为只要存在lastupdated缓存文件,刷新也不会重新下载。本地仓库中,根据依赖的gav属性依次向下查找文件夹,最终删除内部的文件,刷新重新下载即可!
通常这种情况都是因为下载到一半发生了网络问题导致的。
解决办法除了上面找到对应文件夹之后,还可以用一个可执行脚本:
修改之后启动即可。
这段脚本的意思就是找到后缀为lastUpdated的文件删掉即可。
Mavne项目构建及周期概念:
构建概念:
项目构建是指将源代码、依赖库和资源文件等转换成可执行或可部署的应用程序的过程,在这个过程中包括编译源代码、链接依赖库、打包和部署等多个步骤。
项目的构建流程
命令 | 描述 |
---|---|
mvn clean | 清理编译或打包后的项目结构,删除target文件夹 |
mvn compile | 编译项目,生成target文件 |
mvn test | 执行测试源码 (测试) |
mvn site | 生成一个项目依赖信息的展示页面 |
mvn package | 打包项目,生成war / jar 文件 |
mvn install | 打包后上传到maven本地仓库(本地部署) |
mvn deploy | 只打包,上传到maven私服仓库(私服部署) |
我们照着这个命令看上面的构建过程的时候,我们需要要知道,如果我们直接执行打包这个步骤,前面的几个步骤也都会执行
构建命令周期:
构建生命周期可以理解成是一组固定构建命令的有序集合,触发周期后的命令,会自动触发周期前的命令!也是一种简化构建的思路!
清理周期:主要是对项目编译生成文件进行清理
包含命令:clean
默认周期:定义了真正构件时所需要执行的所有步骤,它是生命周期中最核心的部分
包含命令:compile - test - package - install / deploy
报告周期
包含命令:site
打包: mvn clean package 本地仓库: mvn clean install
这里的周期和命令还有插件如何理解呢?
把这里的周期想象成大老板,命令想象成经理,插件想象成工人
老板一步不会直接找工人,先找经理,经理再去找工人,工人真正做事情
我们从这个案例也可以知道,插件才是构建我们项目的真正工具。
Maven工程继承关系
继承概念
Maven 继承是指在 Maven 的项目中,让一个项目从另一个项目中继承配置信息的机制。继承可以让我们在多个项目中共享同一配置信息,简化项目的管理和维护工作。
在父工程中统一管理项目中的依赖信息,进行统一版本管理!
它的背景是:
对一个比较大型的项目进行了模块拆分。
一个 project 下面,创建了很多个 module。
每一个 module 都需要配置自己的依赖信息。 它背后的需求是:
多个模块要使用同一个框架,它们应该是同一个版本,所以整个项目中使用的框架版本需要统一管理。
上一个案例:
以苍穹外卖举例:
苍穹外卖的父工程pom文件:
首先修改了打包方式:改成了pom方式
第二个指定了底下的子模块
这里用了<dependencyManagement>这个标签进行了版本管理,将里面用到的依赖都指定好了版本
Maven工程聚合关系
聚合关系很好理解
就是父工程打包或者将自己这个项目下载带maven仓库里面的时候会把子工程一起带上
这样理解就行。
关于web项目和springboot项目小思考
其实尚硅谷老师在讲这些东西的时候,用maven项目构建了很多的web工程,也教我们怎么去将一个普通项目构建成web项目,其实在他说可以将我们的项目打包成war包,然后部署在服务器上,我就很有疑问了,我昨天刚刚部署完这个项目,为什么我打的是jar包呢?
我问了GPT:
非常好的问题!你提到的“Web工程是用来放在服务器上的”这句话,通常是从“Web应用程序”的定义出发的。Web应用程序通常指的是在服务器上运行并通过网络提供服务的应用。这类应用程序可以用不同的方式进行部署,其中最常见的几种方式如下:
1. WAR包部署:
- 对于典型的Java Web应用程序,通常使用WAR(Web Application Archive)包格式进行打包。这个包通常会包含所有的Web组件(如Servlet、JSP、HTML、CSS等)以及依赖的库文件。在服务器(例如Tomcat、Jetty等)上部署WAR包,即可运行Web应用。
2. JAR包作为Spring Boot应用:
- 对于使用Spring Boot开发的Web应用,通常会打包成一个可执行的JAR(Java Archive)文件。Spring Boot允许在这个JAR中嵌入一个Web服务器(如Tomcat、Jetty),这意味着你可以直接运行这个JAR包并启动内嵌的Web服务器。这样,JAR包可以不仅仅是一个库,还可以作为独立的应用程序直接部署和运行。
3. 微服务架构:
- 如果你的项目是基于微服务架构的,那么每个微服务都可以打包成JAR文件,并独立运行。这些微服务可以在不同的服务器上运行,也可以在相同的服务器上运行,通过网络进行互相通信。
总结
虽然传统的Web工程一般指的是WAR包部署,但目前的开发实践中,尤其是使用Spring Boot的情况下,JAR包也是可以直接用于Web应用程序的部署的。这为开发者提供了更为灵活和便利的部署方式。
所以在你提到的情况下,使用JAR包来部署Web项目是完全合理的,尤其是如果你使用了Spring Boot的话。这样可以让你的应用更容易进行独立部署和管理
我们可以从上面得知,springboot项目有内置tomcat 这种服务器软件,所以,我们直接打成jar包就行,
并且我在上面也没有记录什么关于web项目的东西,我觉得不是很常用。