13
0
0

Maven 入门与私有仓库搭建

2026-10-18
2026-10-21

📝 笔记摘要:Maven 入门与私有仓库搭建

这篇整理的是一套能跑通的 Maven 笔记,从「Maven 到底解决了什么」讲起,一路到 pom 文件逐个标签的含义、IDEA 里值得装的插件、SSM 项目的搭建顺序,再讲用 Nexus 搭一套自己的私有仓库,把「下载走私服、上传走私服」两条链路都打通。

私服那部分 Windows 和 Docker 两条部署路都写了,仓库类型怎么选、代理仓库填什么远端地址、聚合仓库勾哪几个,都配了截图。末尾整理了几个实战里真踩过的坑。

1. Maven 解决什么问题

没有 Maven 的时候,项目管理基本靠手工jar包。用久了会遇到两类问题:

jar 包版本不统一
  A 项目要 Spring 5.2,B 项目要 Spring 5.3,同一个 jar 拷来拷去,迟早冲突
换个机器跑不起来
  Windows 上开发好的工程,拷到 Linux 直接报找不到类,因为依赖路径根本不在代码里

Maven 把「这个项目需要什么、从哪来、怎么组装」这三件事写进一个 pom.xml 里,剩下的交给它。

Maven 工作原理:从项目对象模型和依赖管理出发,经构建生命周期阶段和插件,产出 jar 包、源代码、帮助文档、war 包、XML

整套机制可以拆成三块作用:

依赖管理
  jar 包版本写在 pom 里,不用手动拷,冲突有固定规则可循
跨平台构建
  同一份 pom,Windows、Linux 上 mvn package 出来的结果一致
统一项目结构
  所有 Maven 项目长一个样,换项目不用重新找源码在哪

产物也不只是 jar。源码包、帮助文档、war 包、XML 配置,都是插件在生命周期里挂上去的。

构件生命周期阶段通过插件产出 jar 包、源代码、帮助文档、war 包、XML

2. 生命周期

Maven 的生命周期有三组,互不相干:

clean 生命周期:清理上一轮的产物
  pre-clean → clean → post-clean
default 生命周期:编译、测试、打包、发布的主线
  validate → compile → test → package → verify → install → deploy
site 生命周期:生成项目站点文档,和打包无关

注意:clean 是独立于其他生命周期的一条线,不属于 default。写 mvn clean package 实际上是依次调用两条生命周期里的目标,中间以空格分隔,不是从 clean 一路串到 package。

常用阶段各自的产出:

compile 编译主代码到 target/classes
test   运行单元测试
package  打 jar(war 项目出 war)
verify  校验打包结果,格式校验类插件挂在这
install  把产物装进本地仓库
deploy  把产物推到远程仓库

项目结构也是 Maven 规定的标准布局,新建项目时目录应该是这样:

Maven 标准项目目录:src/main/java、src/main/resources、src/test/java

3. 安装与配置

去官网下 apache-maven-3.6.3-bin.zip,这是稳定版。解压后的目录长这样:

Maven 解压后目录:bin、boot、conf、lib、LICENSE、NOTICE、README

bin 放可执行命令,boot 是启动器,conf 里的 settings.xml 是全局配置,lib 是依赖库。conf 这个目录后面改镜像、改私服全靠它。

改环境变量之前,先记住一个判断依据——

提示:IDEA 点运行 maven 命令时,实际调的就是 MAVEN_HOME/bin/mvn。所以 MAVEN_HOME 配错,IDE 里的构建一定跟着错,命令行却可能还正常(因为命令行是用别的 mvn)。以 IDEA 的表现来验证最准。

配环境变量的入口在 Windows 的「此电脑 → 属性 → 高级系统设置 → 环境变量」:

Windows 系统属性对话框中通过高级系统设置进入环境变量

配三项:

JAVA_HOME
  JDK 的安装根目录,比如 C:\Program Files\Java\jdk1.8.0_291
MAVEN_HOME
  Maven 解压根目录,比如 I:\apache-maven-3.6.3
PATH 追加
  %MAVEN_HOME%\bin

%MAVEN_HOME% 这种写法比写死绝对路径好,换机器改一个变量就够了。验证方式是在命令行敲 mvn -v,能打印出 Apache Maven 和 Java 版本就说明两个 HOME 都对上了。

改 conf/settings.xml,两处最常动:

localRepository 本地仓库路径
  默认在 C:\Users\你的用户名\.m2\repository,换到 I:\maven-repo\javaee-repo,C 盘就不会被撑爆
mirrors 镜像地址
  国内拉依赖慢,用阿里云加速

<settings>
  <localRepository>I:\maven-repo\javaee-repo</localRepository>

  <mirrors>
    <mirror>
      <id>aliyun</id>
      <name>aliyun maven</name>
      <url>https://maven.aliyun.com/repository/public</url>
      <mirrorOf>central</mirrorOf>
    </mirror>
  </mirrors>
</settings>

4. 仓库体系

依赖从哪来,取决于它躺在哪一层:

本地仓库 机器上的缓存目录
  依赖第一次拉下来就放这儿,之后再构建直接命中本地,不再走网络
远程仓库 公网上的官方仓库
  比如 Maven 中央仓库,只有本地没有才会去请求
私服仓库 公司/团队自己搭的
  放内部构件,同时代理公网依赖,充当本地和中央之间的缓冲

仓库体系:A 项目与本地仓库、本地仓库与私服/阿里云之间的依赖拉取关系

以 A 项目第一次引入 jedis 为例:

pom 里写了 <dependency> jedis,Maven 先翻本地仓库
  有 → 直接用,结束
  没有 → 按 <mirror> 配置去私服找
  私服有 → 下载一份到本地仓库,再交给编译器
  私服也没有(代理的公网仓库可能有)→ 私服去远程仓库拉,拉完缓存在自己那儿,同时分发一份到你的本地仓库

这就是私服存在的意义:第二个同事构建同一个项目时,直接从他搭的私服拿,不用每个人都去访问中央仓库。

5. Maven 坐标

一个依赖在 Maven 里靠三元组唯一定位,缺一个都定位不到:

groupId   组织名,一般是公司域名反写,如 org.springframework
artifactId  模块名,同一组织内唯一,如 spring-core
version   版本号

开发中的版本用 1.0-SNAPSHOT,表示随时会变;正式发布去掉这个后缀,写 1.0。IDEA 里新建模块会让你填这三项:

IDEA 中填写 GroupId、ArtifactId、Version 三项坐标

一个完整的 pom 骨架:

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0
                             http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>org.example</groupId>
    <artifactId>demo</artifactId>
    <version>1.0-SNAPSHOT</version>
    <packaging>war</packaging>

    <properties>
        <maven.compiler.source>1.8</maven.compiler.source>
        <maven.compiler.target>1.8</maven.compiler.target>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    </properties>
</project>

提示:<packaging> 不写默认是 jar,出 web 项目才写 war。<properties> 里的 maven.compiler.source/target 不写会跟着当前 JDK 走,团队里 JDK 版本不统一时构建结果就不一致了,写死更稳。

6. IDEA 上值得装的两个插件

Maven Helper,装上以后 pom 文件右键会多一个 Dependency Analyzer:

IDEA 插件市场搜索 maven,安装 Maven Helper pom.xml 右键 Dependency Analyzer 面板展示依赖树

面板会分三栏列出:被使用的依赖、声明但未使用的依赖(灰色,可以删)、被其他依赖间接引入的依赖。排查 NoSuchMethodError 这类冲突时,先来这里看同一个 jar 是不是进了两个版本。

maven-search,用来替代浏览器搜 mvnrepository:

maven search 面板搜索 spring,直接给出坐标和可复制的依赖片段

搜到之后右侧直接生成可复制的 maven 和 gradle 依赖片段,省得手打坐标。快捷键 Ctrl + Shift + M,菜单入口在 Tools → Maven Search。

7. pom 文件详解

出处:本节标签说明与示例取自 Introduction to the POM(Apache Maven 官方文档,Apache License 2.0)

7.1 根元素

<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0
                             http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    ...
</project>

<modelVersion> 固定写 4.0.0,这是 POM 本身的 schema 版本,和项目版本无关

7.2 parent 继承

<parent>
    <groupId>org.example</groupId>
    <artifactId>parent</artifactId>
    <version>1.0-SNAPSHOT</version>
    <relativePath>../pom.xml</relativePath>
</parent>

relativePath 决定去哪找父 pom
  默认 ../pom.xml,即当前目录的上一级
  写 <relativePath/>(空元素)表示本地找不到,直接去仓库按坐标找
  父 pom 在更深的位置就写相对路径,如 ../../parent/pom.xml
能继承到什么
  dependencies、dependencyManagement、build 里的配置、properties
不能继承什么
  artifactId、name、properties 里项目自己定义的属性会覆盖父的

7.3 build 路径管理

不写 <build> 时,Maven 用一套约定路径。写在 <build> 里可以改掉:

<build>
    <sourceDirectory>src/main/java</sourceDirectory>
    <scriptSourceDirectory>src/main/scripts</scriptSourceDirectory>
    <testSourceDirectory>src/test/java</testSourceDirectory>
    <outputDirectory>target/classes</outputDirectory>
    <testOutputDirectory>target/test-classes</testOutputDirectory>
</build>

sourceDirectory    主源码目录,默认 src/main/java
testSourceDirectory  测试源码目录,默认 src/test/java
outputDirectory    主代码编译输出,默认 target/classes
testOutputDirectory  测试代码编译输出,默认 target/test-classes
scriptSourceDirectory  脚本源目录

7.4 build 资源管理

<build>
    <resources>
        <resource>
            <directory>src/main/resources</directory>
            <targetPath>targetPath</targetPath>
            <filtering>false</filtering>
            <includes>
                <include>**/*.properties</include>
            </includes>
            <excludes>
                <exclude>**/*.java</exclude>
            </excludes>
        </resource>
    </resources>
    <testResources>
        <testResource>
            <directory>src/test/resources</directory>
        </testResource>
    </testResources>
</build>

directory  资源所在目录
targetPath  拷贝到 outputDirectory 下的哪个子路径
filtering  是否启用变量替换,详见下方说明
includes  只打包匹配的,支持 ** 通配
excludes  排除匹配的

filtering 是什么:开启后,资源文件里写的 ${project.version} 会在打包时被替换成 pom 里的真实值。所以生产环境的数据库地址可以抽成 env.properties,只在一份 pom 里维护。

7.5 pluginManagement 与 plugins

<build>
    <pluginManagement>
        <plugins>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-jar-plugin</artifactId>
                <version>3.2.0</version>
            </plugin>
        </plugins>
    </pluginManagement>

    <plugins>
        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-jar-plugin</artifactId>
        </plugin>
    </plugins>
</build>

pluginManagement 只声明不启用
  作用是统一锁版本,子模块引用这个插件时可以省略 version
plugins    真正执行构建
  这条才让插件挂到生命周期上

提示:为什么每个项目都要显式声明 maven-compiler-plugin 之类的版本?因为 Maven 的内置插件版本跟着 Maven 版本走,团队里 Maven 版本不同时,构建出来的产物行为会不一致。在 pluginManagement 里统一锁死版本是最省事的做法。

7.6 build 其他元素

<build>
    <extensions>
        <extension>
            <groupId>com.example</groupId>
            <artifactId>some-extension</artifactId>
            <version>1.0</version>
        </extension>
    </extensions>

    <defaultGoal>clean</defaultGoal>
    <directory>${project.basedir}/target</directory>
    <finalName>${project.artifactId}-${project.version}</finalName>
    <filters>
        <filter>src/main/resources/filters.properties</filter>
    </filters>
</build>

extensions  打包阶段的扩展,用得少,做特殊打包格式时才碰
defaultGoal 敲 mvn 不带参数时执行的阶段
directory  构建输出根目录,默认 target
finalName  产物文件名,不写默认是 artifactId-version
filters   filtering 时用到的属性文件,一个 filter 可以供多处资源引用

7.7 dependencies 依赖声明

<dependencies>
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-context</artifactId>
        <version>5.3.8</version>
        <type>jar</type>
        <scope>compile</scope>
        <optional>false</optional>
        <exclusions>
            <exclusion>
                <groupId>commons-logging</groupId>
                <artifactId>commons-logging</artifactId>
            </exclusion>
        </exclusions>
    </dependency>
</dependencies>

type    依赖类型,默认 jar。取 war、ejb、test-jar 等
classifier 同一 groupId + artifactId 下的附加物,如 sources、javadoc
systemPath 引用本地绝对路径的 jar,Maven 3 起不推荐,会告警
optional  true 表示这个依赖不会传递给依赖本项目的下游
exclusions 排除掉某个传递依赖,用来解冲突

scope 决定依赖在哪些阶段可见,一共五个取值:

compile  编译、测试、运行全都要,不写默认就是它
provided  编译和测试需要,运行期由容器提供,不打进包。servlet-api 属于这类
runtime  运行期需要但编译期用不到,比如 JDBC 驱动
test    只在测试阶段有效,不会传递
system   直接指向本地文件,已废弃,别用

提示:打包出的 war 里没有 provided 依赖,这是设计如此,不是漏配。Tomcat 容器自己会提供 servlet-api,重复打进 war 反而会冲突。

7.8 dependencyManagement 版本集中管理

<dependencyManagement>
    <dependencies>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-framework-bom</artifactId>
            <version>5.3.8</version>
            <type>pom</type>
            <scope>import</scope>
        </dependency>
    </dependencies>
</dependencyManagement>

只声明版本,不实际引入依赖
  子模块写 <dependency> 时可以省掉 version,自动继承这里的版本
import 是特殊 scope,只能用在 pom 类型上
  作用是导入一份 BOM,把里面所有管理的版本一次性引进来

父子项目里,子模块的 <dependencies> 真正加依赖,父模块的 <dependencyManagement> 锁版本,这个组合是多模块项目最常用的写法。

8. Maven 搭建 SSM 项目

在 IDEA 里用 Maven 搭一个 Spring + SpringMVC + MyBatis 的 web 项目,顺序是固定的:

IDEA 新建 webapp 项目,Project SDK 选好,Artifact 选 xxx:war exploded
导入 Maven 依赖,确认 pom 已生成
配置 springmvc.xml,扫描 controller 包
配置 web.xml,前端控制器指向 DispatcherServlet
配置 applicationContext.xml,扫 service 和 dao 层
写 jdbc.properties,数据源参数
分层建包:domain、service、impl、controller、dao、mapper
写 Mapper 接口和对应的 Mapper.xml
配置 Tomcat 发布,访问首页

SSM 项目搭建的九个步骤清单

提示:第 2 步和第 9 步最容易漏。IDEA 新建 webapp 项目时勾上 Use Maven for dependencies 才会生成 pom;不发布的话依赖注入全是空指针,报错位置还离真正原因很远。

9. Nexus 私有仓库搭建

Nexus 是最常搭的 Maven 私服,一个进程同时干三件事:代理公网仓库、存放团队内部构件、给前端/npm 等其他生态提供仓库。

9.1 Windows 部署

下载 nexus-3.42.0-01-win64.zip 解压后,先配环境变量,方式和 Maven 一样:

新建系统变量 NEXUS_HOME 指向 Nexus 解压目录

PATH 里追加 bin 目录:

PATH 中追加 %NEXUS_HOME%\bin

Nexus 要占用的端口写在配置文件里,不改的话默认是 8081,和别的东西容易撞。路径是 sonatype-work/nexus3/etc/nexus-default.properties:

nexus-default.properties 中修改 application-port 为 8088
application-port=8088
application-host=0.0.0.0

然后启动,Windows 版进 bin 目录执行:

nexus.exe /run

首次启动会跑一会儿内嵌的 Elasticsearch,日志刷完之前页面访问不了。起来之后打开 http://localhost:8088,用 admin 登录。Nexus 3.17 以后初始密码是随机生成的,在数据目录里:

Nexus 数据目录中的 admin.password、karraf.pid、lock、port 等文件

登录进去第一件事是去 Administration → Security → Anonymous Access 把匿名访问打开,否则拉依赖会被 401 拦住。开放之前先想清楚:开放之后这个 Nexus 就变成团队内部谁都能拉包的状态了。

提示:默认只监听本机(127.0.0.1)。要给别人访问,把 application-host 改成 0.0.0.0,同时确认防火墙放行了端口,并给 admin 换个密码。内网私服不要直接暴露到公网。

9.2 Docker 部署

已经有 Docker 环境的话直接上镜像,比 Windows 版省事:

docker pull sonatype/nexus3

mkdir /data/nexus-data
chown -R 200 /data/nexus-data

docker run -d -p 8081:8081 \
    --name nexus \
    --restart always \
    -v /data/nexus-data:/nexus-data \
    sonatype/nexus3

chown -R 200 这一步不能省:容器里的 Nexus 以 UID 200 运行,宿主机目录属主不对的话容器写不进去,日志里只会报权限错误,很难一眼看出原因
端口映射:容器内固定 8081,要改对外端口只改冒号左边
-v 挂载数据目录:不挂载的话容器一删,所有仓库配置和构件全丢

9.3 建仓库

登录后进 Administration → Repositories → Create repository,能看到当前所有仓库:

Nexus Repositories 列表页,右上角 Create repository 按钮被箭头标注

创建时会先让选 recipe,Maven 依赖选 maven2 (proxy):

Select Recipe 列表中选择 maven2 (proxy)

三种 recipe 的分工:

proxy  代理远端仓库,本地没有就转发过去拉,拉完缓存在 Nexus 里
hosted  自己往里放东西,团队 mvn deploy 的目标
group  聚合,把几个仓库挂在一个 URL 下,对外只暴露一个地址

建 proxy,远端地址填阿里云,国内拉取比中央仓库快很多:

maven-central 代理仓库设置,Remote storage 填阿里云地址

建 hosted,官方仓库不会帮你建 releases 和 snapshots,得自己建两个,版本策略选 Release 或 Snapshot:

maven-releases 私有仓库设置,URL 处被红框标注

建 group,把 proxy 和两个 hosted 都加进 members,配好之后对外就一个 URL:

maven-public 分组仓库设置,Members 列表包含 releases、snapshots、central

建完之后仓库列表就齐了:

Browse 页面显示 maven-central、maven-public、maven-releases、maven-snapshots

maven-central 是自带的代理仓库,maven-public 是自己建的聚合仓库,另外两个是自己建的私有仓库。

9.4 下载走私服

改 settings.xml,加一个 mirror 把所有请求都转给 Nexus:

<mirrors>
    <mirror>
        <id>nexus</id>
        <mirrorOf>*</mirrorOf>
        <url>http://localhost:8088/repository/maven-public/</url>
    </mirror>
</mirrors>
<mirrorOf>*</mirrorOf>  所有仓库都走这个镜像
<mirrorOf>central</mirrorOf> 只镜像中央仓库
<mirrorOf>external:*</mirrorOf> 镜像所有远程仓库,本地仓库不受影响

改完清一次本地缓存重新拉,Nexus 的 Browse 里就能看到缓存下来的构件。

settings.xml 中 mirrors 配置,nexus 镜像用 mirrorOf 星号覆盖全部仓库 Nexus Browse 中 maven-central 仓库缓存的依赖目录树

提示:mirrorOf 写 * 时,Nexus 一挂掉所有依赖都拉不动,整个团队的构建会一起停摆。写 external:* 至少本地仓库不受影响。

注意:老配置里常见的 http://jcenter.bintray.com/ 已经停止服务了,2021 年底就下线,现在配着只会拉不到包。遇到依赖从 jcenter 解析的报错,把那个 mirror 换成 https://maven.aliyun.com/repository/public 或直接指向 Maven 中央仓库。

9.5 上传走私服

上传需要认证,settings.xml 里配 server,id 要和 pom 里 distributionManagement 的 id 对上:

<servers>
    <server>
        <id>nexus-releases</id>
        <username>admin</username>
        <password>你的私服密码</password>
    </server>
    <server>
        <id>nexus-snapshots</id>
        <username>admin</username>
        <password>你的私服密码</password>
    </server>
</servers>

注意:密码写在 settings.xml 里是明文。这份文件不进 git 仓库,也别拷到别人机器上。Nexus 支持 settings-security.xml 做加密,也可以给每个人建独立的 Nexus 账号,各自配各自的 server。

pom 里声明发到哪里:

<distributionManagement>
    <repository>
        <id>nexus-releases</id>
        <name>Nexus Releases</name>
        <url>http://localhost:8088/repository/maven-releases/</url>
    </repository>
    <snapshotRepository>
        <id>nexus-snapshots</id>
        <name>Nexus Snapshots</name>
        <url>http://localhost:8088/repository/maven-snapshots/</url>
    </snapshotRepository>
</distributionManagement>

然后执行:

mvn deploy

Maven 会按版本号自动分流:带 -SNAPSHOT 的发到 snapshotRepository,正式版本发到 repository。所以两个私有仓库都要建,缺一个 deploy 就会报错。

10. 实战问题

10.1 让 B 项目引用 A 项目

A 项目在本地,B 项目要用它,走正常依赖引用是找不到的。把 A 装进本地仓库,B 里再按坐标引:

<dependency>
    <groupId>com.example</groupId>
    <artifactId>A</artifactId>
    <version>1.0-SNAPSHOT</version>
</dependency>

A 如果是 Spring Boot 项目,默认打出来的是 Spring Boot 专用的 jar,包一层 BOOT-INF 目录,普通 Maven 项目当依赖引入时读不到里面的 class。要先把它变成普通 jar,在 A 的 pom 里加:

<plugin>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-maven-plugin</artifactId>
    <configuration>
        <skip>true</skip>
    </configuration>
</plugin>

<plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-resources-plugin</artifactId>
    <version>2.4.3</version>
    <configuration>
        <resources>
            <resource>
                <directory>src/main/resources</directory>
                <filtering>false</filtering>
            </resource>
        </resources>
    </configuration>
</plugin>

<plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-surefire-plugin</artifactId>
    <version>2.5</version>
    <configuration>
        <skipTests>true</skipTests>
    </configuration>
</plugin>

spring-boot-maven-plugin 的 skip 关掉重打包,不再生成带 BOOT-INF 的可执行 jar
maven-resources-plugin   指定从 src/main/resources 打包,绕开 Boot 的资源目录
maven-surefire-plugin    跳过测试阶段,避免测试依赖拖垮 B 项目

提示:这套配置会让 A 失去 Spring Boot 的启动器,本地开发 A 自己时要用 spring-boot:run,不能 java -jar。另外务必确认 A 和 B 用的是同一个 settings.xml 和同一个本地仓库——本地仓库路径不一致,B 就会去私服找一个根本没 deploy 过的版本,然后报找不到构件。

10.2 package、install、deploy 的区别

package 编译、测试、打包,产物在 target 下,出了这个目录就没了
install package 之后,把产物装进本地仓库,其他本地项目能引用
deploy install 之后,再把产物推到远程私服,团队其他人能拉

执行顺序是逐级包含的:install 会自动先跑 package,deploy 会自动先跑 install。

10.3 pom 打包和 jar 打包的区别

pom 类型 只写依赖配置和构建配置,不含源码,一般给多模块项目的父工程用
jar 类型 默认类型,包含编译后的 class 和资源,可以被引用也可以执行

父工程打包成 pom,子模块写 <parent> 指过来,版本、插件、依赖管理全部由父工程统一下发。多模块项目的根目录那个项目,<packaging> 就是 pom。

💡 补充几个原文没写的:

跳过测试别去改 pom
  临时不想跑测试,加命令行参数 mvn package -DskipTests,比在 pom 里锁死 surefire 2.5 版本干净。改 pom 那个写法是为了一次配长期生效,代价是整个团队都跳测试
查依赖冲突用命令行
  mvn dependency:tree -Dverbose,被冲突掉的依赖会标 omitted for conflict,比在 IDEA 里一层层翻快
快照不更新
  改了别人的 SNAPSHOT 依赖但拉的还是旧的,mvn clean install -U,-U 强制检查远程快照
私服挂了不至于全线停摆
  <mirrorOf> 用 external:* 而不是 *,本地已缓存的依赖不依赖网络
Maven 和 JDK 版本要一起锁
  内置插件版本跟着 Maven 版本走,团队里 Maven 版本不统一时,在 pluginManagement 里锁死关键插件版本是最直接的解法

🔥 一句话总结:Maven 把依赖和构建都收进一个 pom 撑着,本地仓库当缓存、settings.xml 管镜像和私服,私服跑起来之后下载改 <mirror>、上传改 <distributionManagement> 加 mvn deploy,剩下的坑基本都出在版本和路径没统一上。

支持与分享

如果这篇文章对你有帮助,欢迎分享给更多人或者给予支持!