Maven在使用过程中的核心知识点总结

题记

世界上只有一种真正的英雄主义,那就是在认清生活的真相后依然热爱生活。
道阻且长,行则将至;行而不辍,未来可期。

前言

Maven 在我们实际工作中,是经常使用的。都知道 Maven 是一个项目管理工具,可以对 Java 项目进行构建、依赖管理。接下来将从实际项目出发进行总结!

Maven 核心概念

这是使用 Maven 的基础,决定了对其功能的掌控程度:

  • POM(Project Object Model,项目对象模型)

    每个 Maven 项目的根目录下必有 pom.xml 文件,它是项目的 "身份证" 和 "配置中心",包含项目基本信息(如 groupId、artifactId、version,即 GAV 坐标)、依赖管理、构建配置(插件、生命周期)等。

    • GAV 坐标 :是项目的唯一标识,groupId 通常为公司域名反转(如 com.example),artifactId 为项目名,version 遵循语义化版本(如 1.0.0-SNAPSHOTSNAPSHOT 表示快照版,用于开发中迭代)。
  • 生命周期(Lifecycle)

    Maven 定义了三套独立的生命周期(cleandefaultsite),每个生命周期包含多个阶段(Phase),执行后续阶段会自动触发前置阶段。

    • 常用场景:mvn clean package 会先执行 clean 生命周期的 clean 阶段(删除 target 目录),再执行 default 生命周期的 package 阶段(打包成 jar/war)。
  • 插件(Plugin)

    生命周期的阶段由插件的目标(Goal)实现,例如 compiler 插件的 compile 目标负责编译 Java 代码,surefire 插件的 test 目标负责运行单元测试。

二、依赖管理

这是 Maven 最核心的功能之一,解决项目中 "jar 包冲突""版本混乱" 等问题:

  1. 依赖声明

pom.xml<dependencies> 中添加依赖,通过 GAV 坐标定位,Maven 会自动从仓库下载并加入类路径。

xml 复制代码
   <dependencies>
          <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-context</artifactId>
            <version>5.3.20</version>
          </dependency>
   </dependencies>   
  1. 依赖传递与排除
  • 依赖具有传递性:若 A 依赖 B,B 依赖 C,则 A 会间接依赖 C(可通过 mvn dependency:tree 查看依赖树)。

  • 排除不需要的传递依赖:使用 <exclusions> 避免冲突,例如排除 Spring 依赖中的日志框架冲突:

    xml 复制代码
    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-context</artifactId>
      <version>5.3.20</version>
      <exclusions>
        <exclusion>
          <groupId>commons-logging</groupId>
          <artifactId>commons-logging</artifactId>
        </exclusion>
      </exclusions>
    </dependency>
  1. 依赖范围(Scope)

    控制依赖在不同生命周期阶段的可用性,常用范围:

    • compile(默认):编译、测试、运行阶段都有效(如 Spring 核心包)。
    • test:仅测试阶段有效(如 JUnit)。
    • provided:运行时由容器提供(如 Servlet API,避免与 Tomcat 内置版本冲突)。
    • runtime:编译不依赖,运行时依赖(如 JDBC 驱动)。
  2. 版本管理与统一

    • 使用 <dependencyManagement> 在父 POM 中声明版本,子模块只需声明 GAV 中的 groupId 和 artifactId,继承父模块的版本,确保项目中依赖版本统一。

    • 示例(父 POM):

      xml 复制代码
      <dependencyManagement>
       <dependencies>
         <dependency>
           <groupId>org.springframework</groupId>
           <artifactId>spring-context</artifactId>
           <version>5.3.20</version>
         </dependency>
       </dependencies>
      </dependencyManagement>

三、仓库管理

Maven 通过仓库存储和获取依赖,需理解仓库类型及配置:

  • 本地仓库 :默认位于 ~/.m2/repository(Windows 为 C:\Users\用户名.m2\repository)(可自行配置仓库地址),存储下载的依赖,避免重复下载。

  • 远程仓库

    • 中央仓库(默认):Maven 官方仓库(repo.maven.apache.org/maven2),包含绝大多数开源依赖。

    • 私有仓库(如 Nexus、Artifactory):企业内部使用,用于管理私有依赖、缓存中央仓库资源,需在 settings.xmlpom.xml 中配置:

      xml 复制代码
      <repositories>
        <repository>
          <id>company-nexus</id>
          <url>http://nexus.company.com/repository/maven-public/</url>
        </repository>
      </repositories>
  • 仓库优先级:本地仓库 → 配置的远程仓库 → 中央仓库。

四、项目结构与多模块管理

Maven 规定了标准的项目目录结构,便于团队协作和自动化构建:

  1. 标准目录结构

    plaintext 复制代码
    src/
      main/          # 主代码
        java/        # Java 源代码
        resources/   # 配置文件(如 application.properties)
        webapp/      # Web 项目的静态资源(JSP、CSS等,仅 war 包需要)
      test/          # 测试代码
        java/        # 测试类(如 XXXTest.java)
        resources/   # 测试配置文件
    pom.xml          # 项目配置
  2. 多模块项目

    大型项目通常拆分为多个模块(如 corewebservice),通过父 POM 统一管理依赖和配置:

    • 父 POM 的 <packaging>pom,并在 <modules> 中声明子模块:

      xml 复制代码
      <packaging>pom</packaging>
      <modules>
        <module>user-core</module>
        <module>user-web</module>
      </modules>
    • 子模块通过 <parent> 继承父 POM,实现依赖和版本的统一管理。

五、常用命令与插件配置

熟练使用命令和插件是提升效率的关键:

  1. 常用命令

    • mvn clean:清理 target 目录(删除编译、打包产物)。
    • mvn compile:编译主代码。
    • mvn test:运行单元测试(会自动执行 compile)。
    • mvn package:打包(生成 jar/war 到 target 目录)。
    • mvn install:将当前项目安装到本地仓库(供其他本地项目依赖)。
    • mvn deploy:将项目部署到远程仓库(需配置私有仓库)。
    • mvn dependency:tree:查看依赖树(分析冲突)。
    • mvn help:effective-pom:查看生效的 POM(合并父 POM 和当前 POM 后的配置)。
  2. 核心插件配置

    • 编译插件(maven-compiler-plugin) :指定 JDK 版本(避免默认版本过低):

      xml 复制代码
      <plugins>
        <plugin>
          <groupId>org.apache.maven.plugins</groupId>
          <artifactId>maven-compiler-plugin</artifactId>
          <version>3.8.1</version>
          <configuration>
            <source>11</source>  <!-- 源代码版本 -->
            <target>11</target>  <!-- 编译后版本 -->
          </configuration>
        </plugin>
      </plugins>
    • 打包插件(maven-jar-plugin/maven-war-plugin) :自定义打包名称、主类等。

    • 测试插件(maven-surefire-plugin) :配置测试用例过滤、跳过测试(mvn package -DskipTests)等。

六、配置文件与环境隔离

解决不同环境(开发、测试、生产)的配置差异:

  • 使用 profiles :在 pom.xml 中定义不同环境的配置(如数据库连接、依赖版本),通过 -P 激活:

    xml 复制代码
    <profiles>
      <profile>
        <id>dev</id>
        <properties>
          <db.url>jdbc:mysql://dev.db.com:3306/test</db.url>
        </properties>
      </profile>
      <profile>
        <id>prod</id>
        <properties>
          <db.url>jdbc:mysql://prod.db.com:3306/test</db.url>
        </properties>
      </profile>
    </profiles>

    执行命令:mvn package -Pprod(使用生产环境配置)。

  • 外部配置文件 :结合 maven-resources-plugin,将环境相关配置文件(如 application-dev.properties)放在 src/main/resources,通过 profile 动态替换。

七、避免常见问题

  • 依赖冲突 :通过 mvn dependency:tree 找到冲突的 jar 包,使用 <exclusions> 排除低版本或不需要的依赖,或在 dependencyManagement 中指定统一版本(就近原则 :路径短的依赖优先;声明优先原则:同路径下先声明的依赖优先)。

  • 仓库下载慢 :配置国内镜像(如阿里云仓库)到 ~/.m2/settings.xml,加速依赖下载:

    xml 复制代码
    <mirrors>
      <mirror>
        <id>aliyun-maven</id>
        <name>阿里云公共仓库</name>
        <url>https://maven.aliyun.com/repository/public</url>
        <mirrorOf>central</mirrorOf>
      </mirror>
    </mirrors>
    ``
  • 快照版本管理 :开发阶段使用 SNAPSHOT 版本,便于频繁更新;发布时使用正式版本(如 1.0.0),避免线上依赖不稳定。

总结

Maven 的核心在于通过 POM 配置 实现 依赖管理生命周期自动化项目标准化,其价值在团队协作和大型项目中尤为突出。掌握上述要点,能有效解决 "jar 包冲突"、构建流程混乱等问题,从而提升项目开发效率。

相关推荐
louisgeek26 分钟前
Java UnmodifiableList 和 AbstractImmutableList 的区别
java
回家路上绕了弯1 小时前
深度理解 Lock 与 ReentrantLock:Java 并发编程的高级锁机制
java·后端
青云交1 小时前
Java 大视界 -- Java 大数据在智能教育在线课程互动优化与学习体验提升中的应用(386)
java·大数据·flink·在线课程·智能教育·互动优化·学习体验
期待のcode1 小时前
SpringAOP
java·开发语言·spring
Captaincc1 小时前
TRAE 首场 Meetup:8月16日,期待与你在北京相聚
前端·后端·trae
肩塔didi2 小时前
用 Pixi 管理 Python 项目:打通Conda 和 PyPI 的边界
后端·python·github
岁忧2 小时前
(LeetCode 面试经典 150 题) 104. 二叉树的最大深度 (深度优先搜索dfs)
java·c++·leetcode·面试·go·深度优先
麦兜*2 小时前
内存杀手机器:TensorFlow Lite + Spring Boot移动端模型服务深度优化方案
java·人工智能·spring boot·spring cloud·ai·tensorflow·ai编程
dylan_QAQ2 小时前
【附录】相对于BeanFactory ,ApplicationContext 做了哪些企业化的增强?
后端·spring
夏小花花2 小时前
Java 日常开发笔记(小程序页面交互传参-id)
java·微信小程序·vue