Maven从入门到精通(一)

一、Maven简介

一个对 Maven 比较正式的定义是这么说的: Maven 是一个项目管理工具,它包含了一个项目对象模型 (POM: Project Object Model),一组标准集合,一个项目生命周期(Project Lifecycle),一个依赖管理系统(Dependency Management System),和用来运行定义在生命周期阶段(phase)中插件(plugin)目标(goal)的逻辑。

简答说,maven主要解决三个问题:项目对象模型、依赖管理、构建项目。

1、项目对象模型:

现在的项目越来越复杂,模块划分也很多,一个项目可能被划分成了 N 个模块,模块多的话已经不可能通过 package 来进行划分了,maven 的第三个功能就是项目模块拆分。

2、依赖管理:

以前的项目如果你想使用三方 jar 包需要到其官网去下载,然后放入在即的项目中,这种工作繁琐且容易出错,效率低下,而且每个项目都有一份,造成大量重复文件。Maven 的第一个功能就是将 Jar 包放到仓库中统一管理,我们只需要引入 Jar 包的坐标即可自行引入。

Jar 包之间往往是相互依赖的,很多 Jar 包依赖其他 Jar 才能正常工作,这称为依赖关系。如果我们手动导入将是大量的工作,而且还需要注意版本问题,非常繁琐。Maven 的第二个功能就是依赖管理,我们只需引入最外层的依赖,其内部的其他依赖无需关注,会自动引入,方便快捷。

3、构建项目

Maven通过定义清晰的构建生命周期和阶段,如clean、compile、test、package、install、deploy等,可以自动执行编译源代码、运行单元测试、生成文档、打包(如生成JAR、WAR、EAR文件)、安装到本地仓库、发布到远程仓库等任务。开发者只需运行相应的Maven命令,即可完成整个构建过程,无需手动执行每一个步骤。

二、项目对象模型

POM 是 Maven 的核心概念,它是以 XML 格式定义的项目配置文件(通常名为 pom.xml),位于项目的根目录下。POM 包含了项目的基本信息(如项目名、版本、组ID、描述等)、构建规则、依赖关系、插件配置、构建生命周期阶段等关键数据。POM为项目提供了统一的、结构化的描述方式,使得项目在整个生命周期中的行为能够被清晰地定义和控制。

POM包括了所有的项目信息:

  • groupId:项目或者组织的唯一标志,并且配置时生成路径也是由此生成,如org.myproject.mojo生成的相对路径为:/org/myproject/mojo
  • artifactId:项目的通用名称
  • version:项目的版本
  • packaging:打包机制,如pom,jar,maven-plugin,ejb,war,ear,rar,par
  • name:用户描述项目的名称,无关紧要的东西,可选
  • url:应该是只是写明开发团队的网站,无关紧要,可选
  • classifer:分类

其中groupId,artifactId,version,packaging这四项组成了项目的唯一坐标。一般情况下,前面三项就可以组成项目的唯一坐标了。

三、依赖管理

1、依赖管理

Maven 最著名的就是 Maven 的依赖管理,它使得我们不必在到开源项目的官网一个个的下载开源组件,然后放到 classpath,一个依赖声明可以包含如下元素

<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-web</artifactId>
    <version>4.2.7</version>
    <type>jar</type>
    <scope>compile</scope>
    <optional>false</optional>
    <exclusions>
        <exclusion>
            <groupId>org.apache.poi</groupId>
            <artifactId>poi</artifactId>
        </exclusion>
    </exclusions>
</dependency>
  • groupId: 代表项目的所属组织或团体的唯一标识符。groupId 旨在区分不同组织或个人提供的项目,防止命名冲突。它反映了项目在软件生态系统中的位置,类似于包名在 Java 中的作用。
  • artifactid:artifactId 是项目本身的唯一标识符,定义实际项目中的一个maven模块。
  • version:version 表示项目的版本号,用来区分同一项目在不同时间点的发布版本。

以上三个元素构成了基本的坐标三要素,通过三要素能唯一确定一个项目标识。去 Maven 仓库寻找依赖时就是通过三元素来检索的。 除了三元素还包括其他一些元素

1)type:用于指定依赖项的类型,常见的类型包括jar(默认)、war、pom等

2)scope:依赖范围,用于控制依赖与三种classpath的关系,包含6种:compile、provided、runtime、test、system和import;

  • compile:默认范围,编译范围的依赖,它在编译和打包的时候都会把依赖打包进去。
  • test:测试依赖范围,它在编译和打包的时候不会把依赖包打包进去。
  • provided:在编译和测试范围有效,最后生成war包是不会打包进去。
  • runtime:运行时依赖,编译的时候不依赖。

3)import:导入依赖范围。import范围仅在dependencyManagement部分使用,用于导入其他项目的dependencyManagement部分的配置。

4)system:系统依赖范围。表示依赖项已经由系统(如本地文件系统、JDK等)提供,且Maven不会尝试从仓库中获取。

5)optional:在 Maven 项目中,optional 是一个标记在 元素内的属性,它用于指示依赖是否可选。当某个依赖被标记为 optional 时,意味着该依赖不会传递给依赖该项目的其他项目,即便这个被标记为 optional 的依赖是项目的一部分。

6)exclusions:排除传递性依赖

3、版本号

dependencyManagement元素主要用来统一管理依赖项的版本号。

假如父项目的pom文件中声明了如下依赖:

<dependencyManagement>    
    <dependencies>        
        <dependency>            
            <groupId>org.apache.commons</groupId>            
            <artifactId>commons-collections4</artifactId>            
            <version>4.4</version>        
        </dependency>    
    </dependencies>
</dependencyManagement>

那么子项目在添加该依赖时,可以不指定版本号:

<dependencies>		
    <dependency>        
        <groupId>org.apache.commons</groupId>        
        <artifactId>commons-collections4</artifactId>    
    </dependency>
</dependencies>

Maven会自动找到父项目中声明的该依赖项的版本号,如下图所示:

这样的优点是可以统一在父项目中管理依赖项的版本号,如果需要升级版本,只需改动父项目一个地方即可,子项目不用改动。

说明:

1、dependencyManagement只是声明依赖项,并没引入依赖项,子项目仍需显式引入,不过可以不指定版本号。

2、如果子项目不想使用继承的父项目中的版本号,在子项目中指定版本号即可。

4、Maven仓库

Maven 仓库可分为三类:本地仓库、远程仓库和中央仓库。当 Maven 根据坐标加载构件时,首先会检索本地仓库,如果本地仓库没有才去远程仓库下载,如果没有配置远程仓库,就去默认的中央仓库下载。

5、依赖传递

在Maven中,依赖是会传递的,假如在业务项目中引入了spring-boot-starter-web依赖:

<dependency>    
    <groupId>org.springframework.boot</groupId>    
    <artifactId>spring-boot-starter-web</artifactId>  	
    <version>2.7.4</version>
</dependency>

那么业务项目不仅直接引入了spring-boot-starter-web依赖,还间接引入了spring-boot-starter-web的依赖项:spring-boot-starterspring-boot-starter-jsonspring-boot-starter-tomcatspring-webspring-webmvc

Maven依赖关系如下图所示:

外部库如下图所示:

其中,业务项目对spring-boot-starter-web的依赖称为直接依赖,对spring-boot-starter-web的依赖项(如下)称为间接依赖:

spring-boot-starterspring-boot-starter-jsonspring-boot-starter-tomcatspring-webspring-webmvc

四、生命周期

Maven 生命周期是 Maven 构建过程的核心概念,它为项目构建提供了一个标准化和自动化的框架。Maven 定义了一系列有序的构建阶段(phase),这些阶段构成了不同的生命周期。当运行 Maven 命令时,Maven 会按照特定生命周期的顺序执行相应的阶段,从而完成整个构建过程。

Maven 拥有三套独立的生命周期:clean、default和site。

1、clean:clean生命周期的目的是清理项目

2、default:default生命周期定义了真正构建时所需执行的所有步骤,如mvn clean instal

  • validate:验证项目是否正确且所有必要的信息都可用。
  • compile:编译项目的源代码。
  • test:编译测试源代码并在断言框架下运行测试。
  • package:把编译好的代码打包成可发布的格式,如jar、war、ear等。
  • integration-test:如果有集成测试,运行集成测试。
  • verify:验证集成测试的结果,确保包质量。
  • install:将打包好的工件安装到本地Maven仓库中。
  • deploy:将最终的工件部署到远程仓库中。

3、site:site生命周期的目的是建立和发布项目站点,maven能够基于pom所包含的信息,自动生成一个友好的站点,方便团队交流和发布项目信息,如执行:mvn clean deploy site-deploy

相关推荐
丶白泽24 分钟前
重修设计模式-结构型-桥接模式
java·设计模式·桥接模式
o独酌o30 分钟前
递归的‘浅’理解
java·开发语言
无问81742 分钟前
数据结构-排序(冒泡,选择,插入,希尔,快排,归并,堆排)
java·数据结构·排序算法
customer081 小时前
【开源免费】基于SpringBoot+Vue.JS在线文档管理系统(JAVA毕业设计)
java·vue.js·spring boot·后端·开源
Flying_Fish_roe1 小时前
Spring Boot-版本兼容性问题
java·spring boot·后端
程序猿进阶1 小时前
如何在 Visual Studio Code 中反编译具有正确行号的 Java 类?
java·ide·vscode·算法·面试·职场和发展·架构
slandarer2 小时前
MATLAB | R2024b更新了哪些好玩的东西?
java·数据结构·matlab
Dola_Pan2 小时前
Linux文件IO(一)-open使用详解
java·linux·dubbo
摇滚侠2 小时前
spring cxf 常用注解
java·后端·spring
路ZP2 小时前
网络编程的应用
java