Maven核心内容详解与实践

443 阅读6分钟

「这是我参与2022首次更文挑战的第7天,活动详情查看:2022首次更文挑战」。

一、Maven简介

本文将分享关于Maven的学习,Maven是一个项目管理工具,将项目开发和管理过程抽象成一个项目对象模型(POM),用于项目构建、依赖管理、统一开发结构。Maven 曾是 Jakarta 项目的子项目,现为由 Apache 软件基金会主持的独立 Apache 项目。其优点是统一开发项目结构、统一jar包资源管理,避免资源冲突。缺点是有一定的学习成本、项目模块间通过pom互相依赖,新手不易理清相互之间的关系。做Java开发的都需要了解并使用Maven,让我们一起来学习Maven吧。

二、依赖管理

2.1 依赖传递

2.1.1 直接依赖

直接依赖指在当前项目中通过依赖配置建立的依赖关系。使用标签定义,比如common模块直接依赖log4j:

2.1.2 间接依赖

间接依赖指通过传递过来的依赖称为间接依赖。比如login依赖了common模块,common模块依赖了log4j,login模块也能使用log4j。

2.2 依赖传递冲突

2.2.1 路径优先

路径优先指当依赖中出现相同的资源时,层级越深,优先级越低,层级越浅,优先级越高。比如login模块依赖了common模块,common模块依赖了log4j的1.2.13版本,login模块在pom中又直接依赖了log4j的1.2.14版本,那么根据路径优先原则会使用log4j的1.2.14版本。

2.2.2 声明优先

声明优先指当资源在相同层级被依赖时,配置顺序靠前的覆盖 配置顺序靠后的。比如common模块配置了log4j的1.2.13版本,user模块配置了log4j的1.2.14版本,根据声明优先原则,优先使用1.2.14版本。

2.2.3 特殊优先

特殊优先指当同级配置了相同资源的不同版本,后配置的覆盖先配置的。比如common模块同时配置了log4j的1.2.13版本和1.2.14版本,根据特殊优先原则,1.2.14版本生效。

2.2.4 可选依赖

可选依赖指对外隐藏当前所依赖的资源。比如common模块配置了lombok,但不想让其他模块使用,这个时候我们可以使用true来隐藏该依赖。

2.2.5 排除依赖

当我们不想使用其他模块的依赖资源时,可以手动排除依赖。比如common模块依赖了lombok,login依赖了common,这个时候login模块间接的依赖了lombok,我们通过排除该依赖。

2.3 依赖范围

依赖的jar包默认情况可以在任何地方使用,可以通过scope标签设定其作用范围。 作用范围:

  • 主程序范围有效(main文件夹范围内)
  • 测试程序范围有效(test文件夹范围内)
  • 是否参与打包(package指令范围内)

2.3.1 scope

Maven中使用 scope 来指定当前包的依赖范围和依赖的传递性

scope标签可选值:

  • compile:默认依赖有效范围
  • provided:编译、测试时有效,运行时无效
  • runtime:运行、测试时有效,编辑时无效
  • test:测试时有效
  • system:编译、测试时有效,运行时无效。和provided的区别是,使用system范围的依赖时必须通过systemPath元素显式地指定依赖文件的路径

三、生命周期与插件

3.1 生命周期

Maven 构建生命周期定义了一个项目构建跟发布的过程,简单说就是运行的阶段。

Maven对项目构建的生命周期划分为三种:

  • clean:项目清理工作
  • default或build:核心工作,比如项目编译、测试、打包、部署
  • site:产生报告、发布站点

3.2 插件

插件与生命周期内的阶段绑定,执行到对应生命周期时执行对应的插件功能。默认Maven在各个生命周期上绑定有预设的功能,通过插件还可以自定义功能。

常用的插件:

  • clean:构建之后清理目标文件并删除目标目录
  • compiler:编译Java源文件
  • surefile:运行JUnit单元测试,创建测试报告
  • jar:从当前工程中构建JAR文件
  • war:从当前工程中构建WAR文件
  • javadoc:为工程生成Javadoc
  • antrun:从构建过程的任意一个阶段中运行一个ant任务的集合

我们可以使用build标签定义构建项目,在IDEA右侧可以方便的使用插件。

还可以点击M图标,打开列表能看到更多的插件命令。

四、聚合与继承

4.1 聚合

聚合用于快速构建Maven工程,一次构建多个模块。聚合模块需要写上pom,否则会默认打成jar包,聚合操作的模块最终执行顺序和模块间的依赖有关系,和配置顺序无关。

4.2 继承

通过继承可以实现在子工程中沿用父工程中的配置,在子工程中声明其父工程坐标与对应的位置。子工程不用声明依赖的版本号,会使用父工程配置的依赖版本号,如果定义版本号则使用自己定义的版本号。能够解决各个模块版本不统一的问题。需要注意的是:父工程配置完依赖后,子工程也需要配置依赖,只是不用声明依赖版本号。

<!--定义该工程的父工程-->
<parent>
    <groupId>com.pzc</groupId>
    <artifactId>project</artifactId>
    <version>1.0-SNAPSHOT</version>
    <!--填写父工程的pom文件-->
    <relativePath>../project/pom.xml</relativePath>
</parent>

<dependencies>
    <dependency>
        <groupId>log4j</groupId>
        <artifactId>log4j</artifactId>
    </dependency>
    <dependency>
        <groupId>org.projectlombok</groupId>
        <artifactId>lombok</artifactId>
    </dependency>
</dependencies>

在父工程中定义依赖管理,声明哪些依赖可以被使用。

<!--声明此处进行依赖管理-->
<dependencyManagement>
    <dependencies>
        <dependency>
            <groupId>log4j</groupId>
            <artifactId>log4j</artifactId>
            <version>1.2.14</version>
        </dependency>
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <version>1.18.20</version>
        </dependency>
    </dependencies>
</dependencyManagement>

4.3 继承与集合的区别

作用:

聚合用于快速构建项目

继承用于快速配置

相同点:

聚合与继承的pom.xml文件打包方式都是pom,可以将两种关系制作到同一个pom文件中

聚合与继承属于设计模块,并没有实际的模块内容

不同点:

聚合是在当前模块中配置关系,聚合可以感知到参与聚合的模块有哪些

继承是在子模块中配置关系,父模块无法感知哪些子模块继承了自己

五、属性

使用标签可以定义一个或者多个属性,在pom文件中的任意位置通过${属性名}的方式使用该属性值,这样就能消除重复和统一管理。属性分为自定义属性、内置属性(version、basedir)、Setting属性(setting.localRepository)、Java系统属性 、环境变量属性。

接下来我们用自定义属性来设置下版本号。

<!--自定义属性-->
<properties>
    <spring-version>5.3.0</spring-version>
</properties>

<!--声明此处进行依赖管理-->
<dependencyManagement>
    <dependencies>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-context</artifactId>
            <version>${spring-version}</version>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-jdbc</artifactId>
            <version>${spring-version}</version>
        </dependency>
    </dependencies>
</dependencyManagement>

六、版本管理

版本管理使用标签1.0.0-SNAPSHOT进行设置。

6.1 工程版本

SNAPSHOT(快照版本):快照版本会随着开发进展不断更新

RELEASE(发布版本):发布版本,如果功能进行更新,也不会改变当前发布版本内容工程版本号约定

6.2 约定规范

约定规范:

<主版本>.<次版本>.<增量版本>.<里程量版本>

主版本:表示项目重大架构变更

次版本:表示有较大功能增加和变化

增量版本:表示有重大漏洞的修复

里程碑版本:表示一个版本的里程碑,和下一个正式版本相比不太稳定

范例:

2.0.0.1.RELEASE

七、总结

Maven的知识点并不算太多,但pom标签很多,我们先掌握常用的标签即可,其他标签需要我们主动去尝试和使用。关于Maven的学习到这里就结束了,如果对你有些许帮助请点赞收藏。

入门篇:Maven入门学习