重来认识一下Maven

一. 什么是Maven

  • Maven是一个基于项目对象模型(Project Object Model, 简称POM)的Java项目管理和构建工具。它通过使用POM文件、目录结构和集中存储库来简化项目的配置和依赖管理,使得开发者可以快速构建、管理和发布Java项目。
  • Maven的主要功能包括自动化构建过程(如编译、测试、打包、发布等),提供标准化的项目结构和管理方式,以及管理项目的依赖。

二. Maven的核心概念

2.1坐标

Maven坐标是用于唯一标识项目中的构件(如jar包)的一组规则。这些规则包括了几个关键元素:groupIdartifactIdversionpackagingclassifier
其中,groupId、version、artifactId是必须的,它们共同定义了一个项目的唯一标识符;packaging是可选的,它指定了构件的打包格式;classifier也是可选的,用来帮助定义构建输出的一些附属构件。示例如下:

<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-core</artifactId>
    <version>6.1.6</version>
</dependency>
元素 描述
groupId 定义当前模块隶属的实际Maven项目, 表示方式与Java包类似Maven项目隶属的实际项目,命名方式通常与域名反向一一对应。必须定义
artifactId 实际项目中的一个Maven项目(模块),推荐使用实际项目名称作为artifactId的前缀。必须定义
version Maven项目当前所处的版本。必须定义
packaging Maven项目的打包方式,打包方式通常与所生成构件的文件扩展名对应。当没有定义时,Maven会使用默认值jar。
classifier 帮助定义构件输出的一些附属附件。注意,不能直接定义项目的classifier,因为附属构件不是项目直接默认生成的,而是由附加的插件帮助生成的。

2.2依赖

在pom中定义project下的dependencies元素可以包含一个或者多个dependency元素来声明一个或者多个项目依赖。

元素 描述
groupId, artifactId, version 依赖的基本坐标
type 依赖的类型,对应于坐标的packaging,默认jar
scope 依赖的范围,用来控制依赖与三种classpath(编译classpath、测试classpath、运行classpath)的关系
optional 标记依赖是否可选
exclusions 用来排除传递性依赖
<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-web</artifactId>
    <version>6.1.6</version>
    <type>jar</type>
    <scope>compile</scope>
    <optional>false</optional>
    <exclusions>
        <exclusion>
            <groupId>log4j</groupId>
            <artifactId>log4j</artifactId>
        </exclusion>
    </exclusions>
</dependency>

Maven提供了dependency插件可以对Maven项目依赖查看以及优化

2.3 依赖范围

  • maven在编译项目主代码时需要使用一套classpath,编译项目主代码时需要用到的jar包会以依赖的方式被引入到classpath中。
  • maven在编译和执行测试这两个阶段会使用不同的classpath。
  • 依赖范围就是用来控制与这三种classpath(编译classpath,测试classpath,运行classpath)的关系。

Maven中有以下几种依赖范围:

依赖范围 含义
compile 编译依赖范围,默认范围。对于编译,测试,运行三种classpath都有效。
test 测试依赖范围。只对于测试classpath有效,在编译主代码和运行主程序中不会被用到。例如junit
provided 已提供依赖范围。对于编译和测试classpath有效,但在运行时无效。例如servlet-api
runtime 运行时编译依赖,对于测试和运行classpath有效,但在编译主代码时无效。例如数据库驱动。
system 系统依赖范围,和provided依赖范围完全一致,但必须通过systemPath显示指定依赖范围的路径,往往与本机系统绑定,谨慎使用
import 导入依赖范围。不会对三种classpath有影响。

2.4 版本依赖顺序

Maven的版本依赖顺序主要遵循以下原则:

  1. 直接依赖优先于间接依赖: 如果一个项目直接依赖于某个库,那么这个库会优先于其他间接依赖被加载。这是因为直接依赖是项目明确声明的,而间接依赖可能是通过其他库间接引入的。

  2. 路径最短原则:当存在多个相同版本的依赖时,Maven会选择路径最短的依赖作为最终的依赖。这意味着从当前项目到该依赖的路径长度越短,该依赖就越优先被加载。

  3. pom文件中声明的顺序:如果两个或更多的依赖具有相同的路径长度(即深度相同),那么Maven会根据pom文件中声明的顺序来决定使用哪个依赖。声明位置在最前面的依赖优先级最高。

  4. 父项目和子项目的覆盖规则:如果有父项目(parent pom)和子项目(child pom),子项目中的依赖声明将覆盖父项目中的相应声明。这允许在不同层次的项目中指定不同的依赖版本。

这些原则共同构成了Maven处理依赖关系的基本机制,帮助开发者有效地管理和解决依赖冲突问题。

2.5 生命周期

maven将其架构和结构的组织放置到了components.xml 配置文件中,该配置文件的路径是:apache-maven-${version}\lib\maven-core-${version}.jar\META-INFO\plexus\conponents.xml文件中。

其中,我们可以看到关于default生命周期XML节点配置信息,一个项目的生命周期抽象成了23个阶段:

<component>
    <role>org.apache.maven.lifecycle.Lifecycle</role>
    <implementation>org.apache.maven.lifecycle.Lifecycle</implementation>
    <role-hint>default</role-hint>
    <configuration>
        <id>default</id>
        <phases>
            <phase>validate</phase>
            <phase>initialize</phase>
            <phase>generate-sources</phase>
            <phase>process-sources</phase>
            <phase>generate-resources</phase>
            <phase>process-resources</phase>
            <phase>compile</phase>
            <phase>process-classes</phase>
            <phase>generate-test-sources</phase>
            <phase>process-test-sources</phase>
            <phase>generate-test-resources</phase>
            <phase>process-test-resources</phase>
            <phase>test-compile</phase>
            <phase>process-test-classes</phase>
            <phase>test</phase>
            <phase>prepare-package</phase>
            <phase>package</phase>
            <phase>pre-integration-test</phase>
            <phase>integration-test</phase>
            <phase>post-integration-test</phase>
            <phase>verify</phase>
            <phase>install</phase>
            <phase>deploy</phase>
        </phases>
    </configuration>
</component>

maven生命周期各个阶段的行为与maven默认行为:

  • mvn compile 让当前项目经历生命周期中的1-->7 阶段 :完成编译主源代码编译
  • mvn package 让当前项目经历生命周期中的1-->17阶段 :完成打包
  • mvn install 让当前项目经历生命周期中的1-->22阶段 :完成包安装到本地仓库
  • mvn deploy 让当前生命经历生命周期中的1-->23阶段 :完成包部署到中心库中

三. Maven仓库

对与maven的生命周期,引出了Maven仓库的概念。Maven仓库主要用于管理项目中所依赖的第三方库,这些库包括但不限于JAR文件、WAR文件、ZIP文件和POM文件等。通过Maven仓库,可以有效地管理和维护项目中的构件(构件指的是任何的依赖、插件、项目输出的jar包)

3.1 本地仓库

  • 本地仓库的默认目录是:/.m2/repository,如果用户需要自定义的仓库目录,编辑/.m2/settings.xml,设置localRepository即可。
  • 默认情况下~/.m2/settings.xml是不存在的,可以从maven安装目录复制conf/settings.xml文件再进行编辑。当然也可以直接修改conf/settings.xml文件,前者配置优先于后者。
  • 一个构件只有在本地仓库中之后,才能由其他maven项目使用。

3.2 远程仓库

  • 中央仓库就是一个默认的远程仓库,maven的安装文件自带了中央仓库的配置。Maven内置了远程公用仓库:https://mvnrepository.com/
  • 每个用户只有一个本地仓库,但是可以配置多个远程仓库。
  • 可以修改settings.xml或者在pom文件,使用<repositories>元素来声明一个或多个远程仓库。
  • 每个远程仓库都需要通过<repository>元素来定义,其中必须包含id、name和url三个属性。id是远程仓库的唯一标识,name是为了方便阅读而设置的名称,而url则是指向该仓库地址的URL

3.3 私服

  • 搭建Maven私服主要有以下几种方式:最主流的是使用Nexus,除此之外还有Artifactory和Apache Archiva(不常用)
  • 私服是一种特殊的远程仓库,架设在局域网内的仓库服务,私服代理广域网上的远程仓库,供局域网内的maven用户使用。
  • 当maven需要下载构件的时候,从私服请求,如果私服上不存在此构件,则从外部的远程仓库中下载,缓存在私服之后,再为maven下载请求提供服务。此外,一些无法从外部仓库中下载到的构件也能从本地上传到私服供大家使用。
  • 使用私服能够带来如下好处:节省网络(外网)带宽、加速maven构建、部署第三方构建:特指一些构件不能从远程仓库中获得、 提供稳定性,增强控制、降低中央仓库的负荷等

参考链接

Maven官网
Maven中文官网
Maven怎么做版本控制器
Maven 项目生命周期与构建原理

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 213,099评论 6 492
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 90,828评论 3 387
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 158,540评论 0 348
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,848评论 1 285
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 65,971评论 6 385
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,132评论 1 291
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,193评论 3 412
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,934评论 0 268
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,376评论 1 303
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,687评论 2 327
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,846评论 1 341
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,537评论 4 335
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,175评论 3 317
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,887评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,134评论 1 267
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,674评论 2 362
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,741评论 2 351

推荐阅读更多精彩内容