当前位置: 首页 > news >正文

Maven介绍

Maven介绍

说了怎么多Maven的优势,Maven到底是什么呢?

MavenApache 软件基金会组织维护的一个项目管理和构建自动化工具,主要用于 Java 项目(也支持其他语言),核心功能是标准化项目结构、自动化构建流程、统一依赖管理Maven这个单词的含义是专家,行家。

标准化项目结构

传统 Java 项目中,不同开发者可能会自定义目录结构(如源码放src还是java,配置文件放conf还是resources),导致团队协作时需要花时间适应彼此的结构,降低效率。

Maven 的解决方式:强制规定了标准化的项目目录结构,所有 Maven 项目都遵循统一规范

例如:

开发目录src

  • 源码目录: src/main/java
  • 测试代码目录: src/test/java
  • 资源文件目录:src/main/resources

输出目录target

  • 类目录(源码编译后的字节码.class文件所在目录):target/classes
  • 测试类目录(测试代码编译后的字节码.class文件所在目录):target/test-classes

配置文件pom.xml

  • 项目的Maven有关配置的文件pom.xml放在项目根目录下。

开发者直接按标准开发,不要关注目录设计。

自动化构建

构建就是以我们编写的 Java 代码、框架配置文件、国际化等其他资源文件、前端页面和图片等静态资源作为“原材料”,去“生产”出一个可以运行的项目的过程。Java 项目的构建流程包括编译(.java.class)、测试(运行单元测试)、打包(生成 JAR/WAR)、部署(发布到服务器)等步骤,传统方式需要手动执行一系列命令或工具,步骤繁琐且易出错。

Maven 的解决方式:定义标准化的构建生命周期一键自动构建项目

  • 生命周期与插件机制:Maven 定义了一套项目的构建生命周期(如clean(清理)→compile(编译)→test(测试)→package(打包)→deploy(部署)),每个阶段由对应的插件自动完成,开发者只需执行一个命令(如mvn package),即可触发整个流程,无需手动干预。
  1. 清理:删除以前的编译结果,为重新编译做好准备。
  2. 编译:将 Java 源程序编译为字节码文件。
  3. 测试:针对项目中的关键点进行测试,确保项目在迭代开发过程中关键点的正确性。
  4. 报告:在每一次测试后以标准的格式记录和展示测试结果。
  5. 打包:将一个包含诸多文件的工程封装为一个压缩文件用于安装或部署。Java 工程对应 jar 包,Web 工程对应 war 包。
  6. 安装:在 Maven 环境下特指将打包的结果——jar 包或 war 包安装到本地仓库中。
  7. 部署:将打包的结果部署到远程仓库或将 war 包部署到服务器上运行。

3个独立的生命周期

Maven 的项目构建生命周期(Build Lifecycle) 是其核心特性之一,它定义了一套标准化的项目构建流程,将编译、测试、打包、部署等环节串联成一个有序的流程,开发者只需执行简单命令即可触发一系列自动化操作。

Maven3相互独立的生命周期,每个生命周期包含一系列阶段,彼此不干扰。

  1. Clean Lifecycle(清理生命周期)

    用于清理项目构建过程中生成的文件(如编译后的.class文件、打包的 JAR/WAR 等)。

    核心阶段(按执行顺序排列):

    阶段名称作用描述
    pre-clean执行清理前的准备工作(如备份文件)。
    clean删除上一次构建生成的所有文件(默认删除target目录)。
    post-clean执行清理后的收尾工作(如日志记录)。
  2. Default Lifecycle(默认生命周期)

    最核心的生命周期,涵盖了项目构建的主要流程(编译、测试、打包、部署等),包含多达 23 个阶段。

    核心阶段(按执行顺序排列):

    阶段名称作用描述
    validate验证项目是否完整(如检查pom.xml配置是否正确、依赖是否存在)。
    initialize初始化构建状态(如设置变量、创建目录)。
    compile编译项目主源码(将src/main/java下的.java编译为.class,输出到target/classes)。
    test-compile编译测试源码(将src/test/java下的测试代码编译为.class,输出到target/test-classes)。
    test运行单元测试(如 Junit 测试,不要求项目已打包)。
    package将编译后的代码打包为可分发格式(如 JAR、WAR,输出到target目录)。
    install将打包好的文件(如 JAR)安装到本地仓库(供本地其他项目依赖)。
    deploy将打包好的文件部署到远程仓库(供团队其他成员或生产环境使用)。
  3. Site Lifecycle(站点生命周期)

    用于生成项目文档站点(如 API 文档、测试报告、项目说明等)。

    核心阶段(按执行顺序排列):

    阶段名称作用描述
    pre-site生成站点前的准备工作。
    site生成项目站点文档(默认输出到target/site)。
    post-site生成站点后的收尾工作(如检查文档完整性)。
    site-deploy将生成的站点部署到远程服务器(如公司内网文档服务器)。

生命周期的执行规则

  1. 阶段触发,前面全执行

    当执行某个阶段时,Maven 会自动执行该生命周期中所有在它之前的阶段

    例如:

    • 执行 mvn package 时,会先依次执行 validateinitializecompiletest-compiletestpackage
    • 执行 mvn install 时,会先依次执行 validateinitializecompiletest-compiletestpackageinstall
  2. 生命周期独立

    3 个生命周期之间相互独立,执行一个生命周期的阶段不会影响其他生命周期。

    例如:mvn clean package 会先执行clean生命周期的pre-cleanclean,再执行default生命周期到package

生命周期与插件的关系

核心概念

  • 插件(Plugin)Maven 的功能载体,每个插件包含多个目标(Goal)(如maven-compiler-plugincompile目标负责编译代码)。
  • 阶段(Phase):生命周期中的步骤(如compilepackage),插件目标可以绑定到某个阶段,执行阶段时自动触发插件目标
  • 绑定方式:分为默认绑定(Maven 预定义,如compile阶段绑定compiler:compile)和自定义绑定(通过pom.xml手动配置)。

Maven 的生命周期本身只定义 “要做什么”(如compile阶段需要编译代码),而 “具体怎么做”插件(Plugin) 实现。这高度体现软件的依赖抽象而非具体的原则,上层使用者用户可以自定义阶段的操作流程,如自定义打包的执行细节等。

每个阶段默认绑定一个或多个插件的目标(Goal),例如:

  • compile阶段默认绑定 maven-compiler-plugin:compile 目标(负责编译主源码)。
  • test阶段默认绑定 maven-surefire-plugin:test 目标(负责运行单元测试)。
  • package阶段默认绑定 maven-jar-plugin:jar 目标(负责打包 JAR)。

开发者也可以通过pom.xml自定义阶段与插件的绑定(例如给package阶段添加压缩目标)。

自定义阶段与插件的绑定

Maven 中,通过pom.xml自定义阶段(Phase)与插件目标(Goal)的绑定,本质是将插件的具体功能(目标)关联到生命周期的某个阶段,使得执行该阶段时自动触发插件目标。这种机制让你可以扩展 Maven 的默认构建流程(如增加代码检查、自动添加代码、静态分析、文件压缩等步骤)。

通过pom.xml<build><plugins>配置,为指定阶段绑定插件目标,核心配置结构如下:

<project>...<build><plugins><!-- 配置一个插件 --><plugin><groupId>插件所属组织ID</groupId><artifactId>插件名称ID</artifactId><version>插件版本</version><!-- 绑定插件目标到生命周期阶段 --><executions><execution><!-- 执行ID(唯一标识,可选) --><id>自定义ID</id><!-- 绑定到哪个阶段(如compile、package、install等) --><phase>目标阶段</phase><!-- 要执行的插件目标 --><goals><goal>插件目标名称</goal></goals><!-- (可选)目标的配置参数 --><configuration><!-- 插件特定的配置项 --></configuration></execution></executions></plugin></plugins></build>...
</project>

示例 1:在package阶段前执行代码检查(使用 Checkstyle 插件)

Checkstyle 是代码规范检查工具,希望在打包前自动检查代码是否符合规范,若不通过则中断构建。

<plugin><groupId>org.apache.maven.plugins</groupId><artifactId>maven-checkstyle-plugin</artifactId><version>3.2.0</version><executions><execution><id>checkstyle-check</id><!-- 绑定到package阶段前的verify阶段(verify在package之后,这里故意用compile演示阶段顺序) --><phase>compile</phase> <!-- 执行compile时触发检查 --><goals><goal>check</goal> <!-- Checkstyle的check目标:执行检查并报错 --></goals><configuration><!-- 指定检查规则文件(可选,默认用Sun的规范) --><configLocation>checkstyle.xml</configLocation><!-- 若检查失败,中断构建 --><failOnViolation>true</failOnViolation></configuration></execution></executions>
</plugin>

示例 2:在package阶段后自动压缩 JAR 包(使用 Assembly 插件)

希望打包(package)后,自动将 JAR 包压缩成 ZIP 格式分发。

<plugin><groupId>org.apache.maven.plugins</groupId><artifactId>maven-assembly-plugin</artifactId><version>3.4.2</version><executions><execution><id>zip-assembly</id><phase>package</phase> <!-- 绑定到package阶段,打包后执行 --><goals><goal>single</goal> <!-- Assembly的single目标:执行一次打包 --></goals><configuration><!-- 配置压缩规则(可自定义assembly.xml) --><descriptorRefs><descriptorRef>jar-with-dependencies</descriptorRef> <!-- 包含依赖的JAR --></descriptorRefs><archive><manifest><mainClass>com.example.MyMain</mainClass> <!-- 若需要可执行 --></manifest></archive><outputDirectory>${project.build.directory}/zip</outputDirectory> <!-- 输出到target/zip --></configuration></execution></executions>
</plugin>

示例3:排除特定依赖,不将其打包到最终的jar包(胖jar包)

排除特定依赖的<excludes>标签是最常用的配置之一,作用是排除特定依赖,不将其打包到最终的可执行 JAR 包 中

lombok用于在代码中自动生成构造器,get/set方法等,它一般只存在于编译阶段,运行阶段不需要,所以可以将它的依赖jar包排除在最终的jar包外。

<plugin><!-- 1. 插件坐标(唯一标识插件) --><groupId>org.springframework.boot</groupId>  <!-- 插件所属组织(Spring官方) --><artifactId>spring-boot-maven-plugin</artifactId>  <!-- 插件名称 --><!-- 注意:通常Spring Boot项目会通过parent继承版本,这里可省略version --><!-- 2. 插件配置(configuration) --><configuration><!-- excludes:排除不需要打包到最终JAR中的依赖 --><excludes><exclude>  <!-- 具体排除的依赖坐标 --><groupId>org.projectlombok</groupId>  <!-- 依赖组织ID --><artifactId>lombok</artifactId>       <!-- 依赖名称 --></exclude></excludes></configuration>
</plugin>

更多在pom.xml配置插件的配置API,这里不再详述,有机会再总结。

统一依赖管理

Maven统一依赖管理是其核心功能之一,通过标准化的依赖声明传递依赖机制版本控制策略,解决了传统 Java 开发中 “依赖散乱、版本冲突、重复引入” 等问题,实现了项目依赖的集中化、自动化管理。

统一依赖管理的核心目标

  1. 标准化声明:用统一格式描述依赖(坐标),替代手动下载 JAR 包的方式。
  2. 自动化引入:根据声明自动从仓库下载(或引用)依赖,并处理依赖的依赖(传递依赖)。
  3. 版本集中控制:在一个地方管理所有依赖的版本,避免版本混乱。
  4. 冲突自动调解通过规则解决多依赖间的版本冲突,减少手动干预。

依赖坐标

依赖的 “坐标”:唯一标识一个依赖(Maven 通过三要素(GAV) 唯一确定一个依赖,类似 “地址”):

  • groupId:组织 / 公司标识(如org.springframework.boot)。
  • artifactId:项目 / 模块标识(如spring-boot-starter-web)。
  • version:版本号(如2.7.0)。

pom.xml中声明依赖的格式:

<project>...<!--存放多个坐标-->
<dependencies>  <!--编写一个坐标--><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId><version>2.7.0</version></dependency>
</dependencies>...
</project>

依赖传递

当项目依赖 A,而 A 又依赖 B 时,Maven 会自动将 B 也引入项目(无需手动声明 B),这就是传递依赖

例如:

  • 声明spring-boot-starter-web(A),它会自动传递引入spring-coretomcat-embed-core等依赖(B、C…)。

传递规则

  • 依赖范围(scope)会影响传递(如test范围的依赖不会传递到主程序)。

  • 可通过<exclusions>排除不需要的传递依赖(如排除冲突的低版本依赖):

    <dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId><exclusions><!-- 排除传递的tomcat依赖(例如用jetty替代) --><exclusion><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-tomcat</artifactId></exclusion></exclusions>
    </dependency>
    

依赖冲突解决

当项目中同一依赖出现多个版本(如 A 依赖fastjson:1.2.60,B 依赖fastjson:1.2.83),Maven 会通过冲突调解规则自动选择一个版本:

  1. 最短路径优先:依赖路径短的版本被选中(如直接依赖的版本优先级高于传递依赖)。
    • 例:项目直接依赖fastjson:1.2.83(路径长度 1),而 A 依赖fastjson:1.2.60(路径长度 2),则选择 1.2.83。
  2. 声明顺序优先:若路径长度相同,pom.xml中先声明的依赖版本被选中。
  3. 手动指定版本:若自动调解不符合预期,可在dependencyManagement中手动声明版本,强制覆盖传递依赖的版本。

依赖范围(scope:控制依赖的生效范围

scope用于指定依赖在哪些构建阶段生效(如编译、测试、运行),避免不必要的依赖引入:

scope生效阶段(编译 / 测试 / 运行)传递性典型场景
compile全部生效(默认值)主程序和测试都需要的依赖
test仅测试阶段(如 Junit)单元测试依赖
provided编译和测试生效,运行时不打包容器已提供的依赖(如 servlet-api,Tomcat 已包含)
runtime测试和运行生效,编译不生效运行时依赖(如 JDBC 驱动)
import仅在dependencyManagement中生效导入其他pom的依赖管理

示例:

<!-- Junit仅在测试阶段生效 -->
<dependency><groupId>junit</groupId><artifactId>junit</artifactId><version>4.13.2</version><scope>test</scope>
</dependency>
http://www.dtcms.com/a/582565.html

相关文章:

  • C++ 递推与递归:两种算法思想的深度解析与实战
  • WPP Media(群邑)优质服务能力 再度蝉联京东京牌五星认证
  • 装修公司网站建设费用宁波seo基础入门
  • mysql 网站 数据库站长之家工具高清
  • 如何在k8s中配置并使用nvidia显卡
  • 【天野学院5期】 第5期易语言半内存辅助培训班,主讲游戏——手游:仙剑奇侠传4,端游:神魔大陆2
  • 深度学习-损失函数
  • 淮南建设公司网站如何做外围网站的代理
  • 测试开发话题11---自动化测试实战篇
  • 单播、广播、组播
  • 不用建网站怎么做淘宝客wordpress 分类分页
  • 防水网站的外链如何找临汾市网站建设
  • 公司app与网站建设方案网站域名备案密码
  • 【智慧城市】2025年华中农业大学暑期实训优秀作品(2):基于Vue框架和Java后端开发
  • C++面试常见问题
  • 品牌网站建设权威logo库官网
  • AI驱动开发新范式:基于 CodeWave 的考勤系统落地实践
  • PCI总线驱动开发全解析
  • 做网站数据库表设计Wordpress企业主题XShuan
  • 买完域名网站怎么设计房产中介网站开发模板
  • AVL树实现
  • Vue 组件插槽的深层传递
  • HENGSHI SENSE 6.1 发布,从 ChatBI 到 Agentic Analytics
  • 网站 哪些服务器wordpress新编辑器分类
  • 网站进度条源代码juqery-ui泰安网站建设公司
  • 11月7日星期五今日早报简报微语报早读
  • 网站维护一般都是维护什么公司注册网站需要提供什么文件
  • 网站开发现在是热门专业吗福建网站建建设
  • wordpress 首页无法访问seo信息编辑招聘
  • Nginx配置DNS缓存