最全!最强大!Maven知识大全(maven基础知识)
liuian 2025-05-02 19:43 64 浏览
一、什么是Maven
Maven是Apache的一款开源的项目管理工具,是Apache基于ANT进行升级后,研发出了全新的自动化构建工具。
Maven使用项目对象模型(POM-Project Object Model,项目对象模型)的概念,可以通过一小段描述信息来管理项目的构建,报告和文档的项目管理工具软件。在Maven中,每个项目都相当于是一个对象,对象(项目)和对象(项目)之间是有关系的,关系包含了:依赖、继承、聚合,实现Maven项目可以更加方便的实现导jar包、拆分项目等效果,因此,大部分公司项目都采用 Maven 管理。
二、Maven下载
Maven的官网地址如下:http://maven.apache.org/
具体的下载界面如下:
2.1 设置 Maven 环境变量
添加环境变量 MAVEN_HOME
右键 "计算机",选择 "属性",之后点击 "高级系统设置",点击"环境变量",来设置环境变量,有以下系统变量需要配置:
新建系统变量 MAVEN_HOME,变量值:D:\apache-maven-3.8.6(这里是下载的Maven的地址)
编辑系统变量 Path,添加变量值:%MAVEN_HOME%\bin
三、IDEA整合Maven
如下图所示,可以用自己下载的Maven路径替换系统自带的版本。
四、Maven目录结构解析
Maven目录结构如下图所示:
bin:存放的是执行文件和命令,在IDEA中可以直接集成Maven
conf目录:存放的是配置信息,其中有一个非常重要的配置文件settings.xml,这是maven的核心配置文件,是一个全局配置文件。
在电脑C盘的用户主目录下面有一个隐藏文件夹.m2文件夹,这是Maven默认的工作文件夹。如果没有.m2目录 ,可以通过手动执行mvn命令创建。
五、Maven常见命令
常见命令 | 描述 |
install | 本地安装, 包含编译,打包,安装到本地仓库。 |
clean | 清除已编译信息。 |
compile | 只编译, javac命令 |
package | 打包命令,包含编译和打包两个功能。 |
install和package的区别:
package命令完成了项目编译、单元测试、打包功能,但没有把打好的可执行jar包(war包或其它形式的包)布署到本地maven仓库和远程maven私服仓库。
install命令完成了项目编译、单元测试、打包功能,同时把打好的可执行jar包(war包或其它形式的包)布署到本地maven仓库,但没有布署到远程maven私服仓库。
六、Maven仓库
在 Maven 的术语中,仓库是一个位置(place)。Maven 仓库是项目中依赖的第三方库,这个库所在的位置叫做仓库。在 Maven 中,任何一个依赖、插件或者项目构建的输出,都可以称之为构件。
Maven 可以在某个位置统一存储所有的 Maven 项目共享的构件,这个统一的位置就是仓库,项目构建完毕后生成的构件也可以安装或者部署到仓库中,供其它项目使用。
Maven仓库是基于简单文件系统存储的,集中化管理Java API资源(构件)的一个服务。仓库中的任何一个构件都有其唯一的坐标,根据这个坐标可以定义其在仓库中的唯一存储路径。得益于 Maven 的坐标机制,任何 Maven项目使用任何一个构件的方式都是完全相同的。
Maven 仓库能帮助我们管理构件(主要是JAR),它就是放置所有JAR文件(WAR,ZIP,POM等等)的地方。
对于Maven来说,仓库分为两类:本地仓库和远程仓库。
6.1 本地仓库
本地仓库只是本机的一份拷贝,用来缓存远程下载的内容,包含我们尚未发布的临时构件。
运行 Maven 的时候,Maven 所需要的任何构件都是直接从本地仓库获取的。如果本地仓库没有,它会首先尝试从远程仓库下载构件至本地仓库,然后再使用本地仓库的构件。
默认情况下,不管Linux还是 Windows,每个用户在自己的用户目录下都有一个路径名为 .m2/repository/ 的仓库目录。
Maven 本地仓库默认被创建在 %USER_HOME% 目录下。要修改默认位置,在 %M2_HOME%\conf 目录中的 Maven 的 settings.xml 文件中定义另一个路径。
6.2 远程仓库
我们称不在本机中的一切仓库都是远程仓库。远程仓库又分为中央仓库和本地私服仓库。
远程仓库指通过各种协议如file://和http://访问的其它类型的仓库。这些仓库可能是第三方搭建的真实的远程仓库,用来提供他们的构件下载(例如repo.maven.apache.org和uk.maven.org是Maven的中央仓库)。其它“远程”仓库可能是我们的公司拥有的建立在文件或HTTP服务器上的内部仓库(不是Apache的那个中央仓库,而是我们公司的私服,我们在局域网搭建的maven仓库),用来在开发团队间共享私有构件和管理发布的。
默认的远程仓库使用的Apache提供的中央仓库:
Apache的mvn远程仓库:
https://mvnrepository.com/
如果仓库A可以提供仓库B存储的所有内容,那么就可以认为A是B的一个镜像。
在国内直接连接中央仓库下载依赖,由于一些特殊原因下载速度非常慢。这时,我们可以使用阿里云提供的镜像仓库来替换中央仓库。修改 maven 根目录下的 conf 文件夹中的 settings.xml 文件,在 mirrors 节点上,添加内容如下:
6.3 仓库优先级
七、JDK配置
当IDEA中有多个JDK时,需要在Maven中指定编译和运行的JDK,在settings.xml中配置:
注:配置的前提是IDEA中要有1.8的JDK
<profile>
<!-- settings.xml中的id不能随便起的 -->
<!-- 告诉maven我们用jdk1.8 -->
<id>jdk-1.8</id>
<!-- 开启JDK的使用 -->
<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>
八、Maven工程类型
- POM工程:POM工程是逻辑工程。用在父级工程或聚合工程中。用来做jar包的版本控制。
- JAR工程:打包成jar,用作jar包使用。即常见的本地工程 ---> Java Project。
- WAR工程:打包成war,发布在服务器上的工程。
九、IDEA创建Maven工程
项目的标准目录结构如下:
9.1 Maven项目目录介绍
- src:包含了项目所有的源代码和资源文件,以及其他项目相关的文件。
- src/main/java:这个目录下储存java源代码。
- src/main/resources:储存主要的资源文件。比如xml配置文件和properties文件。
- src/test/java:储存测试用的类,比如JUNIT的测试一般就放在这个目录下面。因为测试类本身实际是不属于项目的,所以放在任何一个包下都显得很尴尬,所以maven专门创建了一个测试包,用于存放测试的类。
- src/test/resources:可以自己创建,储存测试环境用的资源文件。
- target:编译后内容放置的文件夹 。
- pom.xml:Maven的基础配置文件。配置项目和项目之间关系,包括配置依赖关系等等。
--test 项目名
--.idea 项目的配置,自动生成的,无需关注。
--src
-- main 实际开发内容
--java 写包和java代码,此文件默认只编译.java文件
--resource 所有配置文件,最终编译把配置文件放入到classpath中。
-- test 测试时使用,自己写测试类或junit工具等
--java 储存测试用的类
pom.xml 整个maven项目所有配置内容。
十、Maven工程关系
10.1 依赖关系
A工程在开发或运行过程中需要B工程提供支持,则说明A工程依赖B工程。
在这种情况下,A项目的pom.xml文件中需要配置定义依赖关系。
10.1.1 如何注入依赖呢?
在pom.xml文件中,根元素project下的 dependencies标签中,配置依赖信息。标签中可以包含多个 dependence元素,以声明多个依赖。
每个依赖dependence标签都应该包含以下元素:groupId、artifactId, version ,这三个是依赖的基本坐标, 对于任何一个依赖来说,基本坐标是最重要的,Maven是根据坐标寻找需要的依赖的。
10.1.2 依赖的优点
- 节省了手动添加jar包的操作,省时省力!!!
- 解决jar包冲突问题。
10.1.3 依赖原则
1.第一原则:最短路径优先原则
“最短路径优先”意味着项目依赖关系树中路径最短的版本会被使用。
例如,假设A、B、C之间的依赖关系是A->B->C->D(1.0) 和A->F->D(2.0),那么D(2.0)会被使用,因为A->F->D(2.0)的路径更短。
2. 第二原则:最先声明原则
依赖路径长度一样长的时候,第一原则就不适用了,比如这样的依赖关系:A–>C–>Y(1.0),A–>D–>Y(2.0),Y(1.0)和Y(2.0)的依赖路径长度是一样长的,都为2。那么到底谁会被解析使用呢?
在maven2.0.8及之前的版本中,这是不确定的,但是maven2.0.9开始,为了尽可能避免构建的不确定性,maven定义了依赖调解的第二原则:最先声明优先。
在依赖路径长度相等的前提下,在POM中依赖声明的顺序决定了谁会被解析使用。顺序最靠前的那个依赖优先使用。
10.1.4 依赖的传递性
依赖传递性是Maven2.0的新特性。
假设项目依赖于一个库,而这个库又依赖于其他库。我们不必自己去找出所有这些依赖,我们只需要加上直接依赖的库,Maven会隐式的把这些库间接依赖的库也加入到我们的项目中。
这个特性是靠解析从远程仓库中获取的依赖库的项目文件实现的。
一般的,这些项目的所有依赖都会加入到项目中,或者从父项目继承,或者通过传递性依赖。
如果B依赖了C,那么A依赖B时会自动把B和C都导入进来。
案例:
项目1:test项目依赖了Mybatis的内容,创建test项目后,选择IDEA最右侧Maven面板lifecycle,双击install后就会把项目安装到本地仓库中,其他项目就可以通过坐标引用此项目。
注:请将项目test打包为jar包
再创建项目test1:让项目test1依赖项目test:
从上面可以证明:
项目test1依赖项目test,项目test依赖Mybatis工程,根据依赖的传递性,项目test1可以直接使用Mybatis工程。
10.1.5 排除依赖
在有些场景中,需要将传递的某部分依赖排除,可以通过exclusions标签实现。
exclusions: 用来排除传递性依赖。在exclusions标签中可配置多个exclusion标签,每个exclusion标签需要配置groupId, artifactId, version三项基本元素(注意:不用写版本号)。
比如:A--->B--->C (Mybatis.jar) 排除C中的Mybatis.jar
10.1.6 依赖范围
传递依赖发现可以通过使用如下的依赖范围来得到限制。依赖范围决定了依赖的坐标在什么情况下有效,什么情况下无效。
范围 | 描述 |
编译阶段(compile) | 该范围表明相关依赖是只在项目的类路径下有效,表明该依赖在编译和运行时都生效。默认取值。 |
供应阶段(provided) | 该范围表明相关依赖是由运行时的JDK或者网络服务器提供的,编译和测试项目的时候需要该依赖,但在运行项目的时候,由于容器已经提供,就不需要Maven重复地引入。 |
运行阶段(runtime) | 该范围表明相关依赖在编译阶段不是必须的,但是在执行阶段是必须的。也就是,编译时不需要生效,而只在运行时生效。 |
测试阶段(test) | 该范围表明相关依赖只在编译测试代码和运行测试的时候需要,应用的正常运行不需要此类依赖。 |
系统阶段(system) | 该范围表明你需要提供一个系统路径。与provided类似,不过必须显式指定一个本地系统路径的JAR,此类依赖应该一直有效,Maven也不会去仓库中寻找它。但是,使用system范围依赖时必须通过systemPath元素显式地指定依赖文件的路径。 |
导入阶段(import) | 该范围只在依赖是一个 pom 里定义的依赖时使用。同时,当前项目的POM 文件的 部分定义的依赖关系可以取代某特定的 POM。import范围只适用于pom文件中的<dependencyManagement>部分。表明指定的POM必须使用<dependencyManagement>部分的依赖。 |
案例:
定义一个父POM工程
定义一个子工程
结论:
子工程不用指定依赖的版本号,这样就可以在父工程进行统一管理。
如果父工程中加入score-import 相当于强制指定了版本号。
10.2 继承关系
如果A工程继承B工程,则代表A工程默认依赖B工程依赖的所有资源,且可以应用B工程中定义的所有资源信息。
被继承的工程(B工程)只能是POM工程。
注:在父项目中放在<dependencyManagement>中的内容是不被子项目继承,不可以直接使用。
放在<dependencyManagement>中的内容主要目的是进行版本管理。里面的内容在子项目中依赖时坐标只需要填写groupId和artifactId即可。(注意:如果子项目不希望使用父项目的版本,可以明确配置version)。
父工程:
子工程:
集成关系本质上是POM文件的继承 。
10.3 聚合关系
如果工程有2个以上模块时,每个模块都是一个独立的功能集合。比如某电商系统中拥有用户中心、商品中心、购物车中心等。在开发的时候每个中心都可以独立编译、测试和运行。这个时候就需要聚合工程。
创建聚合工程时,总的工程必须是一个POM工程(Maven Project)(聚合项目必须是一个pom类型的项目,jar项目和war项目是没有办法做聚合工程的),各子模块可以是任意类型模块(Maven Module)。
聚合包含了继承的特性。
聚合时多个项目的本质还是一个项目。这些项目被一个大的父项目包含。且这时父项目类型为pom类型。同时在父项目的pom.xml中出现<modules>表示包含的所有子模块。
父工程:
子模块:
十一、Maven 构建生命周期
Maven 构建生命周期定义了一个项目构建跟发布的过程。
一个典型的 Maven 构建(build)生命周期是由以下几个阶段的序列组成的:
阶段 | 处理 | 描述 |
验证 validate | 验证项目 | 验证项目是否正确且所有必须信息是可用的 |
编译 compile | 执行编译 | 源代码编译在此阶段完成 |
测试 Test | 测试 | 使用适当的单元测试框架(例如JUnit)运行测试。 |
包装 package | 打包 | 创建JAR/WAR包如在 pom.xml 中定义提及的包 |
检查 verify | 检查 | 对集成测试的结果进行检查,以保证质量达标 |
安装 install | 安装 | 安装打包的项目到本地仓库,以供其他项目使用 |
部署 deploy | 部署 | 拷贝最终的工程包到远程仓库中,以共享给其他开发人员和工程 |
十二、Maven常见插件
12.1 编辑器插件
通过编译器插件,我们可以配置使用的JDK或者说编译器的版本。
1.settings.xml文件中配置全局编译器插件。
通过找到profiles节点,在里面加入profile节点。
<profile>
<!-- 定义的编译器插件ID,全局唯一,名字随便起 -->
<id>jdk-1.8</id>
<!-- 插件标记,activeByDefault :true默认编译器,jdk提供编译器版本 -->
<activation>
<activeByDefault>true</activeByDefault>
<jdk>1.8</jdk>
</activation>
<!-- 配置信息source-源信息,target-字节码信息,compilerVersion-编译过程版本 -->
<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>
2.配置编译器插件:pom.xml配置片段。
<!-- 配置maven的编译插件 -->
<build>
<plugins>
<!--JDK编译插件 -->
<plugin>
<!--插件坐标 -->
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.2</version>
<!-- -->
<configuration>
<!-- 源代码使用JDK版本-->
<source>1.7</source>
<!-- 源代码编译为class文件的版本,要保持跟上面版本一致-->
<target>1.7</target>
<encoding>UTF-8</encoding>
</configuration>
</plugin>
</plugins>
</build>
12.2 资源拷贝插件
Maven在打包时默认只将src/main/resources里的配置文件拷贝到项目中并做打包处理,而非resource目录下的配置文件在打包时不会添加到项目中。
我们的配置文件,一般都放在:src/main/resources
然后打包后配置文件就会在target的classes下面放着:
如果想把非resources下面的文件也打包到classes下面,需要在pom.xml配置如下内容:
12.3 Tomcat插件
我们如果创建war项目,必然要部署在服务器上,有如下方式:
- 部署在远程服务器上。
- 将IDEA和外部Tomcat产生关联,然后将项目部署在外部tomcat上。
其实还有别的方式,不用依赖外部的Tomcat,Maven提供了Tomcat插件,我们可以配置来使用。
12.3.1 创建web项目(war项目)
使用Tomcat插件发布部署并执行war工程的时候,需要使用启动命令,启动命令为: tomcat7:run。
命令中的tomcat7是插件命名,由插件提供商决定;run为插件中的具体功能。
注意:
之前用的编译器插件和资源拷贝插件,不是可运行的插件,Maven直接帮我们运行了。但是Tomcat属于可运行插件,它什么时候工作需要程序员通过命令来运行控制。
具体pom.xml文件的配置如下:
<build>
<plugins>
<!-- 配置Tomcat插件 -->
<plugin>
<groupId>org.apache.tomcat.maven</groupId>
<artifactId>tomcat7-maven-plugin</artifactId>
<version>2.2</version>
<configuration>
<!-- 配置Tomcat监听端口 -->
<port>8080</port>
<!-- 配置项目的访问路径(Application Context) -->
<path>/</path>
</configuration>
</plugin>
</plugins>
</build>
在浏览器中访问index.jsp页面:
相关推荐
- Html中Css样式Ⅱ_html+css+
-
元素的定位(方式五种定位方式):静态定位:position:static;相对定位:position:relative;绝对定位:position:absolute;固定定位:position...
- HTML 标签和属性值的基本格式_html标签及属性的语法规则
-
HTML:HyperTextMarkupLanguage超文本标记语言HTML代码不区分大小写,包括HTML标记、属性、属性值都不区分大小写;任何空格或回车键在代码中都无效,插入空格或回车有...
- C#中使用Halcon开发视觉检测程序教程
-
一、环境准备1.安装Halcon从Halcon官方网站下载适合你操作系统的安装包,按照安装向导完成安装。安装过程中,记住安装路径,后续配置环境时会用到。2.配置VisualStudio项目打开V...
- 【开源】C#功能强大,灵活的跨平台开发框架 - Uno Platform
-
前言今天给广大网友分享一个基于C#开源、功能强大、灵活的跨平台开发框架,她就是:UnoPlatform。通过UnoPlatform,开发者可以利用单一代码库实现多平台兼容,极大地提高了开发效率和...
- C# 的发展简史_c#的发展前景
-
1.C#的诞生和初期(2000-2005)2000年:在微软的PDC大会上,由AndersHejlsberg首次公开展示了C#语言。2002年:微软发布了.NETFramework1.0,其...
- Visual Studio 2010-C#跟西门子1200(Sharp7)窗体控制②-启动按钮
-
VisualStudio2010--C#跟西门子1200(Sharp7)窗体控制②--启动按钮上期回顾(上期主要是新建窗体应用程序,添加sharp7的类库并引用,建立一个button按钮):本期将...
- Visual Studio窗口布局混乱后的恢复与优化指南
-
在使用VisualStudio进行开发时,我们常因误操作(如拖拽窗口、关闭面板、多显示器切换)导致界面布局混乱,代码编辑器、解决方案资源管理器、属性面板等组件“错位”,严重影响开发效率。本文将针对布...
- 使用Visual Studio 2017为AutoCAD创建一个c#模板
-
本教程的目标是展示如何在VisualStudio2017中创建AutoCAD的c#项目模板,该模板允许在调试模式下从VisualStudio加载DLL来自动启动AutoCAD。本文展示的示例使用...
- IT科技-续3Visual Studio2019-C#实战练习
-
上次完成了登录页面的窗体设计,本次完成管理界面的设计。第一步ComBox控制深度操作点击编辑选项,加入预定选项,完成操作。第二步复制Buttons控件依次为保存、删除、重置、编辑按钮属性设置,参考...
- 如何在 C# 中将文本转换为 Word 以及将 Word 转换为文本
-
在现代软件开发中,处理文档内容是一个非常常见的需求。无论是生成报告、存储日志,还是处理用户输入,开发者都可能需要在纯文本与Word文档之间进行转换。有时需要将文本转换为Word,以便生成结构化的...
- 简短的C#入门教程 # C# 入门教程 C#(读作...
-
简短的C#入门教程#C#入门教程C#(读作CSharp)是一种由Microsoft开发的多范式编程语言,它具有广泛的应用,特别是在Windows平台上。本教程将介绍C#的基础知识,以帮助您入门这...
- JavaScript中this指向各种场景_前端中this的指向
-
在JavaScript中,this的指向是一个核心概念,其值取决于函数的调用方式,而非定义位置(箭头函数除外)。以下是this指向的常见场景及具体说明:1.全局作用域中的this在全局作用域(非...
- 微信WeUI设计规范文件下载及使用方法
-
来人人都是产品经理【起点学院】,BAT实战派产品总监手把手系统带你学产品、学运营。WeUI是一套同微信原生视觉体验一致的基础样式库,由微信官方设计团队为微信Web开发量身设计,可以令用户的使用感知...
- JavaScript技术:如何动态添加事件?
-
随着前端技术的不断发展,JavaScript已经成为了不可或缺的一部分,它可以让网页变得更加流畅和美观。但是,在JavaScript中动态添加事件还是一个比较困难的问题,为此,本文将从入门到精通,介绍...
- 一周热门
-
-
【验证码逆向专栏】vaptcha 手势验证码逆向分析
-
Python实现人事自动打卡,再也不会被批评
-
Psutil + Flask + Pyecharts + Bootstrap 开发动态可视化系统监控
-
一个解决支持HTML/CSS/JS网页转PDF(高质量)的终极解决方案
-
再见Swagger UI 国人开源了一款超好用的 API 文档生成框架,真香
-
网页转成pdf文件的经验分享 网页转成pdf文件的经验分享怎么弄
-
C++ std::vector 简介
-
飞牛OS入门安装遇到问题,如何解决?
-
系统C盘清理:微信PC端文件清理,扩大C盘可用空间步骤
-
10款高性能NAS丨双十一必看,轻松搞定虚拟机、Docker、软路由
-
- 最近发表
-
- Html中Css样式Ⅱ_html+css+
- HTML 标签和属性值的基本格式_html标签及属性的语法规则
- 基于Visual Studio C#语言开发上位机,做定制设计后有多好看
- C#中使用Halcon开发视觉检测程序教程
- 【开源】C#功能强大,灵活的跨平台开发框架 - Uno Platform
- C# 的发展简史_c#的发展前景
- Visual Studio 2010-C#跟西门子1200(Sharp7)窗体控制②-启动按钮
- Visual Studio窗口布局混乱后的恢复与优化指南
- 使用Visual Studio 2017为AutoCAD创建一个c#模板
- IT科技-续3Visual Studio2019-C#实战练习
- 标签列表
-
- python判断字典是否为空 (50)
- crontab每周一执行 (48)
- aes和des区别 (43)
- bash脚本和shell脚本的区别 (35)
- canvas库 (33)
- dataframe筛选满足条件的行 (35)
- gitlab日志 (33)
- lua xpcall (36)
- blob转json (33)
- python判断是否在列表中 (34)
- python html转pdf (36)
- 安装指定版本npm (37)
- idea搜索jar包内容 (33)
- css鼠标悬停出现隐藏的文字 (34)
- linux nacos启动命令 (33)
- gitlab 日志 (36)
- adb pull (37)
- python判断元素在不在列表里 (34)
- python 字典删除元素 (34)
- vscode切换git分支 (35)
- python bytes转16进制 (35)
- grep前后几行 (34)
- hashmap转list (35)
- c++ 字符串查找 (35)
- mysql刷新权限 (34)