Maven进阶

三、maven进阶

3.1pom.xml文件

maven的核心配置文件 pom.xml,定义了项目的基本信息、依赖、构建配置等。

Maven Repository: Search/Browse/Explore maven中央仓库链接

3.2坐标

3.2.1坐标的概念

在 Maven 中坐标是构件的唯一标识,Maven 坐标的元素包括 groupIdartifactIdversion 、packaging、classifier。上述5个元素中,groupId、artifactId、version 是必须定义的,packaging 是可选的 ( 默认为 jar )还有var或pom。

3.2.2坐标的意义

  • groupId:组织标识,一般为:公司网址的反写+项目名(唯一标识)
  • artifactId:项目名称,一般为:项目名-模块名
  • version:版本号 形式为0.0.1-SNAPSHOT:
  • 第一个 0 表示大版本号,第二个 0 表示分支版本号,第三个 0 表示小版本号
  • SNAPSHOT -- 快照版本,ALPHA -- 内侧版本,BETA -- 公测版本,RELEASE -- 稳定版本,GA -- 正式发布
  • packaging:打包的方式,如:pom, jar, maven-plugin, ejb, war, ...
  • clissifier:用来帮助定义构件输出的一些附属构件。

自己项目的坐标如下:

第三方项目坐标如下:

3.3依赖

3.3.1依赖的意义

在 Maven 中,依赖(Dependency) 是指你的项目需要使用的 外部库(比如别人写好的工具包、框架等)。Maven 通过依赖管理,帮你自动下载这些库,并确保版本兼容,避免手动操作的麻烦。

想象你在做一道菜:

  • 你的代码 = 你的菜(比如"红烧肉")。

  • 依赖 = 需要的调料(比如酱油、糖、八角)。
    如果没有酱油,菜就做不出来,但你不必自己酿酱油,直接买现成的就行。

Maven 的依赖就是帮你自动"买调料"(下载库),并确保"调料"的版本是对的(比如"生抽"而不是"老抽")。

3.3.2依赖的核心作用

  1. 省去手动下载

    • 传统方式:上网找 JAR 包 → 下载 → 放到项目里 → 可能版本冲突。

    • Maven 方式:在 pom.xml 中写一行配置,自动下载并管理。

  2. 解决依赖冲突

    • 比如你的项目用了库 A,而库 A 又需要库 B,Maven 会自动把 A 和 B 都下载好(传递性依赖)。
  3. 版本统一管理

    • 避免团队中每个人用的库版本不同导致问题。

3.3.3依赖的使用

例如我们的项目需要进行单元测试,则需要使用到junit-4.9.jar包,使用maven引用该依赖的方式如下:

java 复制代码
<dependencies>
		<dependency>
			<groupId>junit</groupId>
			<artifactId>junit</artifactId>
			<version>4.9</version>
			<!--依赖范围-->
			<scope>test</scope>
		</dependency>		
		
		<dependency>
			<groupId>cn.tx.maven</groupId>
			<artifactId>Hello</artifactId>
			<version>0.0.1-SNAPSHOT</version>
			<scope>compile</scope>
		</dependency>	
</dependencies>

属性说明:

**三维坐标:**引用依赖包的三维坐标,用来定位该依赖包;

**scope:**控制该依赖包在什么情况下会被加到 classpath 中;

3.3.4第三方依赖的查找方法

我们在不确定所需引用的第三方依赖包的坐标时,通过maven的中央仓库进行查找,网址: https://mvnrepository.com/;

3.4依赖范围

Maven项目在开发工程中有三套classpath

  • 主代码:main下面的都是主代码在编译的时候的依赖
  • 测试代码:test下是测试代码编译的时候的依赖
  • 运行时:main代码在运行的时候对包的依赖

依赖范围的使用,通过在引用第三方依赖时的<scope></scope>标签进行设置,例如:

java 复制代码
        <dependency>
			<groupId>junit</groupId>
			<artifactId>junit</artifactId>
			<version>4.9</version>
			<!--依赖范围-->
			<scope>test</scope>
		</dependency>		
		

共 6 种 scope,包括:compileprovidedruntimetest 、system、import。例如上图的junit,只在测试中使用,则选择test即可,默认为compile

  • **Compile:**编译依赖范围。默认使用此依赖范围,其下的maven依赖,对于编译,测试,运行classpath都有效。(默认)
  • **Test:**测试依赖范围。只对测试classpath有效,编译主代码或运行项目时无法使用此依赖。典型例子如junit。
  • **Provided:**已提供依赖范围。其对于编译与测试classpath有效,运行时无效。如在web开发时,只有在编译和测试时才用到servlet-api,将其设置为此范围,在运行时servlet-api由web容器提供,无须依赖。并且在打war包时,此范围的依赖不会打在WEB-INF/lib下。(tomcat自带api,如果provided有会发生冲突,或者覆盖)
  • **Runtime:**运行时依赖范围。与provided相对,运行时classpath有效。典型例子如jdbc(编写是接口规范运行是提供具体实现类需要jar包)。

3.5依赖传递和可选依赖

3.5.1依赖传递

应用场景:

第一直接依赖: HelloFriend项目依赖Hello项目

第二直接依赖: MakeFriend项目依赖HelloFriend项目

makeFriend项目只依赖了HelloFriend,但是也把Hello依赖进来了。

传递依赖是会受到依赖范围的影响的,具体来看结果如下:

3.5.2依赖阻断

例如我们在HelloFriend项目里面的Hello依赖处添加该配置

<optional>true:表示Hello只在HelloFriend中

则makeFriend项目里面就不会再引入Hello的依赖。

3.5.3可选依赖

如果我们需要在依赖中明确的排除掉某一依赖,则可以使用exclusion属性,排除掉引用的依赖,如图:

3.6仓库

3.6.1 仓库的概念

Maven 仓库(Repository)是存放和管理项目依赖(第三方库、插件等)的地方,就像是一个**"仓库管理员"**,帮你自动下载、缓存和查找需要的文件。

仓库的类型有:

  • 本地(local)
  • 中央(central)
  • 远程(remote)

3.6.2本地仓库(Local Repository)

  • 作用:相当于你的"个人书架",存储你所有项目下载过的依赖。

  • 位置 :默认在用户目录下的 .m2/repository(例如:C:\Users\你的用户名\.m2\repository)。如果要修改默认位置,在 %Maven_HOME%\conf 目录中的 Maven 的 settings.xml 文件中定义另一个路径。

  • 特点

    • 第一次下载的依赖会缓存到这里,下次直接用,无需重复下载。

    • 只有你自己的电脑能访问。

3.6.3中央仓库(Central Repository)

  • 作用 :Maven 官方维护的公共图书馆,存储了绝大多数开源库(如 Junit、Spring 等)。

  • 地址https://mvnrepository.com/

  • 特点

    • 无需配置,Maven 默认从这里下载依赖。

    • 如果中央仓库没有你需要的依赖,需要手动添加其他远程仓库。

3.6.4远程仓库(Remote Repository)

  • 作用:除了中央仓库以外的其他仓库,可能是公司内部的私有仓库或第三方公共仓库。

  • 常见例子

    • 公司私有仓库(如 Nexus、Artifactory):存放公司内部开发的私有库。

    • 第三方公共仓库(如阿里云镜像仓库):加速下载(替换默认的中央仓库)。

  • 配置方式 :在 pom.xmlsettings.xml 中声明:

java 复制代码
<repositories>
    <repository>
        <id>aliyun</id>
        <url>https://maven.aliyun.com/repository/public</url>
    </repository>
</repositories>

3.6.5三者协作流程

  1. 当你运行 mvn install

    • Maven 先检查本地仓库,如果有依赖,直接使用。

    • 如果本地没有,从中央仓库或配置的远程仓库下载,并缓存到本地仓库。

    • 如果是公司私有库,会从私有远程仓库下载。

  2. 优先顺序
    本地仓库 → 远程仓库(按配置顺序) → 中央仓库

仓库类型 比喻 特点
本地仓库 你家书架 快速拿书,但书不全时要去图书馆借。
远程仓库 公司/学校的图书馆 书更全,但需要联网访问。
中央仓库 国家图书馆 书最多,但距离远(下载可能慢)。

3.7生命周期

Maven的生命周期是对所有的构建过程进行抽象和统一。Maven的生命周期是抽象的,这意味着生命周期本身不做任何实际的工作,生命周期只是定义了一系列的阶段,并确定这些阶段的执行顺序。而在执行这些阶段时,实际的工作还是由插件来完成的。这种思想与设计模式中的模板方法非常相似。

Maven 有 3 个独立的生命周期,每个生命周期包含不同阶段:

(1) clean 生命周期

目的 :清理项目。
主要阶段

  • pre-cleanclean(删除 target 目录) → post-clean
(2) default 生命周期(最常用)

目的 :构建和部署项目。
关键阶段(按顺序执行):

  1. validate(验证项目正确性)

  2. compile(编译源代码)

  3. test(运行单元测试)

  4. package(打包,如生成 JAR/WAR 文件)

  5. verify(检查测试结果)

  6. install(将包安装到本地仓库)

  7. deploy(部署到远程仓库)

(3) site 生命周期

目的 :生成项目文档和报告。
主要阶段

  • pre-sitesite(生成文档) → post-sitesite-deploy(发布文档)

把 Maven 生命周期比作 "盖房子"

  1. clean:拆掉旧房子(清理 target)。

  2. default

    • compile = 打地基(编译代码)。

    • test = 检查工程质量(运行测试)。

    • package = 封顶完工(打包)。

    • install = 把房子登记到本地房产局(本地仓库)。

  3. site:生成房屋使用说明书(项目文档)。

3.8maven的继承和聚合

3.8.1继承的意义

继承允许子模块从父模块继承配置信息,类似于 Java 中的类继承机制。作用是为了

  • 统一管理公共依赖

  • 统一配置插件

  • 统一管理属性

  • 减少重复配置

3.8.2可继承的元素

groupId :项目组 ID ,项目坐标的核心元素;

version :项目版本,项目坐标的核心元素;

description :项目的描述信息;

organization :项目的组织信息;

inceptionYear :项目的创始年份;

url :项目的 url 地址

develoers :项目的开发者信息;

contributors :项目的贡献者信息;

distributionManagerment :项目的部署信息;

issueManagement :缺陷跟踪系统信息;

ciManagement :项目的持续继承信息;

scm :项目的版本控制信息;

mailingListserv :项目的邮件列表信息;

properties :自定义的 Maven 属性;(统一管理版本)

dependencies :项目的依赖配置;

dependencyManagement :醒目的依赖管理配置;

repositories :项目的仓库配置;

build :包括项目的源码目录配置、输出目录配置、插件配置、插件管理配置等;

reporting :包括项目的报告输出目录配置、报告插件配置等。

3.8.3IDEA实现maven的继承

创建父类项目

创建子类项目core

以同样的方式创建manage和portal项目:

至此,一个由parent统一管理core,manage和portal的mavan项目就创建好了;

观察父子项目的pom文件配置

3.8.4继承的依赖管理

父类直接引用依赖,如果在父类的dependencies内直接引用依赖,则子类都会继承该依赖,以mybatis为例:

父类通过dependencyManagement管理依赖,子类不会默认继承该依赖,但是当子类使用该依赖时无需考虑版本信息,直接继承父类dependencyManagement中设置的版本号(Version),以log4j为例:

3.8.5聚合管理

我们在平时的开发中,项目往往会被划分为好几个模块,比如common公共模块、system系统模块、log日志模块、reports统计模块、monitor监控模块等等。这时我们肯定会出现这么一个需要,我们需要一次构件多个模块,而不用每个模块都去mvn;

以上面得父子项目为例,当我们对parent进行mvn install时,会对core,manage和portal项目均进行install操作:

3.8.6properties属性的使用

通过 properties元素用户可以定义一个或多个 maven 属性,然后在 maven 的其他地方使用 ${属性名称} 的方式引用该属性,这种做法的意义在于消除重复和统一管理。比如,需要在多个地方重复声明同样的 SpringFramework 版本,现在只需要在一个地方声明就可以。

相关推荐
真实的菜6 分钟前
Java NIO 面试全解析:9大核心考点与深度剖析
java·面试·nio
飞翔的佩奇21 分钟前
Java项目:基于SSM框架实现的劳务外包管理系统【ssm+B/S架构+源码+数据库+毕业论文】
java·mysql·spring·毕业设计·ssm·毕业论文·劳务外包
luckywuxn37 分钟前
EurekaServer 工作原理
java·eureka
壹米饭39 分钟前
Java程序员学Python学习笔记一:学习python的动机与思考
java·后端·python
java金融42 分钟前
Java 锁升级机制详解
java
Young55661 小时前
还不了解工作流吗(基础篇)?
java·workflow·工作流引擎
让我上个超影吧1 小时前
黑马点评【缓存】
java·redis·缓存
ajassi20001 小时前
开源 java android app 开发(十一)调试、发布
android·java·linux·开源
YuTaoShao1 小时前
Java八股文——MySQL「存储引擎篇」
java·开发语言·mysql
crud1 小时前
Java 中的 synchronized 与 Lock:深度对比、使用场景及高级用法
java