一、Maven 类似前端的什么?
Maven(mvn)在前端没有单一对应物,它同时承担「装依赖 + 定义构建流程 + 调用插件编译打包」几件事。可以把它理解成下面这一组工具的组合:
| Maven | 前端类似物 | 作用 |
|---|---|---|
mvn |
npm / yarn / pnpm | 安装依赖、执行构建命令 |
pom.xml |
package.json |
项目名、版本、依赖列表 |
mvn clean package |
npm run build |
清理旧产物并打包 |
~/.m2/repository |
全局 npm 缓存 | 下载的 jar 存放在本地仓库 |
<dependency> |
dependencies / devDependencies |
声明第三方库 |
| 多模块(api + impl) | monorepo(npm/pnpm workspaces) | 一个仓库里多个子包 |
mvnw / mvnw.cmd |
Volta / Corepack / .nvmrc |
锁定构建工具版本,团队一致 |
.mvn/settings.xml |
.npmrc |
私有源、镜像、认证 |
| Maven 插件 | Vite / Webpack / esbuild | 真正执行编译、打包(如 compiler、spring-boot-maven-plugin) |
一句话记忆
Maven ≈ npm + 一套固定的构建流水线
前端 scripts 里自己写 dev、build、test;Maven 则用固定生命周期阶段:compile → test → package。
常用命令对照
| 目的 | Maven | 前端 |
|---|---|---|
| 安装依赖 | mvn dependency:resolve(构建时自动) |
npm install |
| 本地跑服务 | mvn spring-boot:run |
npm run dev |
| 打生产包 | mvn package |
npm run build |
| 发布到私服 | mvn deploy |
npm publish |
| 跑测试 | mvn test |
npm test |
| 清理 | mvn clean |
rm -rf dist |
二、为什么需要 mvnw 和 mvnw.cmd?
这两个文件是 Maven Wrapper 的启动脚本,功能相同,只是面向不同系统:
| 文件 | 适用环境 |
|---|---|
mvnw |
Linux / macOS / Git Bash |
mvnw.cmd |
Windows(PowerShell / CMD) |
解决的问题
-
不强制本机预装 Maven
首次执行时会按
.mvn/wrapper/maven-wrapper.properties自动下载 Maven 3.9.9。 -
统一团队 Maven 版本
避免「我这边 3.6 能编、你那边 3.9 报错」的环境差异。本项目
spring-boot-maven-plugin对 Maven 版本较敏感,因此锁定 3.9.9。 -
自动加载项目配置
.mvn/maven.config会在每次构建时生效:ini-s .mvn/settings.xml -Dmaven.wagon.http.allowInsecureProtocol=true等价于每次手动加:
powershellmvn -s .mvn/settings.xml -Dmaven.wagon.http.allowInsecureProtocol=true ...其中
settings.xml配置了公司内网 Nexus;allowInsecureProtocol允许访问http://私服。详见 第三节。 -
替代仓库内嵌完整 Maven
以前可能在
.tools/apache-maven-3.9.6放一整份 Maven;Wrapper 只提交小脚本,本体按需下载,是业界常见做法。
和直接 mvn 的关系
.\mvnw.cmd |
系统 mvn |
|
|---|---|---|
| Maven 版本 | 固定 3.9.9 | 取决于本机安装 |
| 项目 settings | 自动加载 | 需手动 -s |
| 是否必须 | 推荐 | 可替代,但不保证版本一致 |
三、.mvn/settings.xml 详解
这是 Maven 的项目级配置文件 ,类似前端的 .npmrc :告诉 Maven 从哪下载 jar、如何访问公司私服(Nexus)。放在项目 .mvn/ 下而非用户目录 ~/.m2/settings.xml,clone 后团队构建行为一致。
通过 .mvn/maven.config 自动加载:
ini
-s .mvn/settings.xml
-Dmaven.wagon.http.allowInsecureProtocol=true
| 参数 | 作用 |
|---|---|
-s .mvn/settings.xml |
使用项目自带的 settings |
-Dmaven.wagon.http.allowInsecureProtocol=true |
允许访问 http:// 私服(Maven 3.8+ 默认拦截 HTTP) |
3.1 <mirrors> --- HTTP 镜像
xml
<mirror>
<id>nexus-http</id>
<mirrorOf>external:http:*</mirrorOf>
<url>http://nexus.os.adc.com/nexus/content/groups/public/</url>
</mirror>
| 字段 | 含义 |
|---|---|
mirrorOf = external:http:* |
所有外部 HTTP 仓库的请求,统一走这个镜像 |
url |
公司内网 Nexus 的 public 组(聚合多个仓库) |
Maven 3.8+ 默认禁止 HTTP 仓库。私服地址是 http://,因此需要 mirror + allowInsecureProtocol 配合使用。类比 npm:把 HTTP 源请求统一转发到公司私服。
3.2 <profiles> --- 仓库列表
定义名为 nexus 的配置集,声明去哪拉依赖。
依赖仓库 <repositories>
| 仓库 id | URL | 拉什么 |
|---|---|---|
central |
https://repo.maven.apache.org/maven2 |
开源正式版(如 Spring Boot) |
nexus-releases |
http://nexus.os.adc.com/.../releases/ |
公司内网正式发布的包 |
nexus-snapshots |
http://nexus.os.adc.com/.../snapshots/ |
公司内网快照版包 |
每个仓库用 <releases> / <snapshots> 控制只拉对应类型。本项目大量依赖 SNAPSHOT(如 crypto-base-function:1.0.6-SNAPSHOT),主要靠 nexus-snapshots。
插件仓库 <pluginRepositories>
xml
<pluginRepository>
<id>central</id>
<url>https://repo.maven.apache.org/maven2</url>
</pluginRepository>
Maven 构建插件 (compiler、spring-boot-maven-plugin 等)的下载源,与项目依赖仓库分开配置。
3.3 <activeProfiles> --- 自动启用
xml
<activeProfiles>
<activeProfile>nexus</activeProfile>
</activeProfiles>
无需每次手动加 -Pnexus,构建时自动激活上面的 nexus profile。
3.4 构建时的解析流程
lua
执行 .\mvnw.cmd clean package
↓
读取 maven.config → 加载 settings.xml + 允许 HTTP
↓
激活 nexus profile → 可用 central + nexus-releases + nexus-snapshots
↓
pom.xml 声明的依赖按类型去对应仓库解析
↓
下载到 ~/.m2/repository(本地缓存,类似 node 全局缓存)
↓
HTTP 请求经 mirror 走 nexus.os.adc.com
3.5 与 pom.xml 的分工
| 文件 | 方向 | 作用 |
|---|---|---|
.mvn/settings.xml |
pull(下载) | 构建时从哪拉依赖和插件 |
pom.xml 的 distributionManagement |
push(发布) | mvn deploy 时往哪推包 |
发布与多模块的完整说明见 第五节。
3.6 前端类比小结
| settings.xml | 前端类似 |
|---|---|
repositories |
.npmrc 里多个 registry= |
nexus-snapshots |
私服上的 beta / nightly 通道 |
mirrors |
npm 镜像源 |
activeProfiles |
默认生效的 registry 配置 |
allowInsecureProtocol |
允许非 HTTPS 源(内网常见) |
3.7 注意点
- 必须连内网 / VPN 才能访问
nexus.os.adc.com,否则 SNAPSHOT 依赖拉不下来。 - 当前文件不含
<servers>账号密码,说明拉包走内网免密或匿名;不要把密码提交进仓库。 - IDE 若直接用系统
mvn且未指定-s .mvn/settings.xml,可能与命令行mvnw行为不一致;建议 IDE Maven 设置指向这份文件,或统一用mvnw。
四、本项目结构速览
bash
crypto-auth-provider/
├── pom.xml # 根 POM(类似根 package.json + workspace 配置)
├── mvnw / mvnw.cmd # Maven Wrapper 入口
├── .mvn/
│ ├── maven.config # 默认 Maven 参数
│ ├── settings.xml # 私服 / Nexus 配置
│ └── wrapper/maven-wrapper.properties
├── crypto-auth-provider-api/ # API 契约模块(类似 shared types 包)
│ └── pom.xml
└── crypto-auth-provider-impl/ # 可运行服务(类似 apps/web)
├── pom.xml
├── conf/ # 本地运行配置(gitignore,需自备)
└── src/main/java/.../Application.java
pom.xml 里常见概念
| Maven | 前端类比 |
|---|---|
<groupId> + <artifactId> |
@scope/package-name |
<version>${revision}</version> |
version 字段 |
<modules> |
workspaces 子包列表 |
<dependencyManagement> |
统一锁版本(类似 resolutions / overrides) |
<dependencies> |
dependencies |
五、多模块与发布(deploy)
日常 mvn clean package 不会上传 任何东西到 Nexus;只有 mvn deploy 才会把产物推到私服。本节说明根 pom.xml 里 <modules>、<distributionManagement> 与各子模块 deploy.skip 如何配合。
5.1 <modules> 是干什么的?
xml
<modules>
<module>crypto-auth-provider-api</module>
<module>crypto-auth-provider-impl</module>
</modules>
这是 多模块聚合(reactor) 声明:在根目录执行 Maven 时,会按顺序构建这两个子项目。类比前端 monorepo 的 workspaces。
| 作用 | 说明 |
|---|---|
mvn clean package |
两个模块都会编译打包 |
mvn deploy |
遍历两个模块,但每个模块是否实际上传另说 |
| 构建顺序 | 先 api,再 impl(impl 依赖 api) |
<modules> 不是「勾选要上传哪个包」 ,只定义「工程里有哪些子项目、构建时一起跑」。指定单个模块用 -pl,例如 mvn deploy -pl crypto-auth-provider-api。
5.2 <distributionManagement> --- 上传目标
xml
<distributionManagement>
<repository>
<id>nexus-releases</id>
<name>Nexus Release Repository</name>
<url>http://nexus.os.adc.com/nexus/content/repositories/releases/</url>
</repository>
<snapshotRepository>
<id>nexus-snapshots</id>
<url>http://nexus.os.adc.com/nexus/content/repositories/snapshots/</url>
</snapshotRepository>
</distributionManagement>
| 节点 | 何时使用 | 地址 |
|---|---|---|
<repository> |
版本不以 -SNAPSHOT 结尾 |
.../repositories/releases/ |
<snapshotRepository> |
版本以 -SNAPSHOT 结尾 |
.../repositories/snapshots/ |
当前版本 ${revision} = 2026.07.01(无 -SNAPSHOT)→ 若 deploy,进 releases 。若改成 2026.07.01-SNAPSHOT,则进 snapshots(同坐标可反复覆盖上传)。
<id> 需与 .mvn/settings.xml 中仓库 id 一致;若 deploy 要账号,在 settings 的 <servers> 里按 id 配置(当前项目 settings 未配 servers,日常多为本机只拉包、由 CI 发布)。
5.3 mvn deploy 流程
在根目录执行 mvn deploy 时:
go
mvn deploy(crypto-auth-provider 根目录)
│
▼
读取 <modules>,建立 reactor 构建顺序
│
├── 1. 根 crypto-auth-provider(packaging=pom)
│ → 可上传父 POM 元数据
│
├── 2. crypto-auth-provider-api(jar)
│ → compile → package → 上传到 Nexus
│
└── 3. crypto-auth-provider-impl(jar)
→ compile → package → 是否上传?看 deploy.skip
│
▼
按 <version> 选择 releases 或 snapshots 仓库
│
▼
上传 jar、pom、sources.jar 等(若该模块未 skip deploy)
每个会 deploy 的模块通常上传:
| 文件 | 作用 |
|---|---|
xxx.jar |
代码包 |
xxx.pom |
坐标与依赖声明 |
xxx-sources.jar |
源码包(若配置了 source 插件) |
5.4 本项目:谁会上传、谁不会?
crypto-auth-provider-impl/pom.xml 中:
xml
<maven.deploy.skip>true</maven.deploy.skip>
表示 impl 不参与 deploy ,即使它在 <modules> 里、会参与 package。
| 模块 | packaging | deploy | 实际上传? |
|---|---|---|---|
根 crypto-auth-provider |
pom |
默认 | 父 POM 元数据 |
crypto-auth-provider-api |
jar |
未 skip | 会上传 ,供其他服务 dependency 引用 |
crypto-auth-provider-impl |
jar |
deploy.skip=true |
不上传(可运行服务,打 tar.gz 给运维部署) |
常见分工:
- api :对外契约(
AuthFacade、DTO)→ 需要npm publish式的发布 - impl :Spring Boot 可执行服务 → 只
package部署,不进 Maven 私服
典型 deploy 结果:api 的 jar 进 Nexus ,impl 仅本地 target/ 产物。
5.5 命令与场景对照
| 命令 | 是否上传 Nexus | 说明 |
|---|---|---|
mvn clean package |
否 | 只打本地 target/ |
mvn install |
否 | 只装到本机 ~/.m2 |
mvn deploy |
是 | 按各模块 skip 规则上传 |
mvn deploy -pl crypto-auth-provider-api |
是(仅 api) | 只发布指定模块 |
发布通常需要:内网可达 Nexus、deploy 权限、settings 中 <servers> 认证(若私服要求)。
5.6 三块配置如何串联
xml
┌─────────────────────────────────────────────────────────┐
│ pom.xml <modules> │
│ → 有哪些子项目、构建顺序 │
└────────────────────┬────────────────────────────────────┘
▼
┌─────────────────────────────────────────────────────────┐
│ 各子模块:packaging、maven.deploy.skip │
│ → 该模块要不要 deploy、产物类型 │
└────────────────────┬────────────────────────────────────┘
▼
┌─────────────────────────────────────────────────────────┐
│ 根 pom <distributionManagement> │
│ → 上传到 Nexus releases / snapshots │
└────────────────────┬────────────────────────────────────┘
▼
┌─────────────────────────────────────────────────────────┐
│ settings.xml <servers>(若配置) │
│ → deploy 认证 │
└─────────────────────────────────────────────────────────┘
5.7 前端类比
| Maven | 前端 |
|---|---|
<modules> |
monorepo workspaces 列表 |
mvn deploy |
npm publish |
maven.deploy.skip |
子包 "private": true 或不参与 publish |
distributionManagement |
publish 目标 registry |
| api 模块 | 可发布的 @scope/crypto-auth-provider-api |
| impl 模块 | 只部署的服务端应用,不 publish 成 npm 包 |
六、构建命令
在项目根目录执行(Windows PowerShell 注意给 -D 参数加引号):
powershell
cd F:\java\crypto-auth-provider
.\mvnw.cmd clean package "-Dmaven.test.skip=true"
成功后会生成:
crypto-auth-provider-impl/target/crypto-auth-provider.jar--- 可执行 jarcrypto-auth-provider-impl/target/crypto-auth-provider-bin.tar.gz--- 部署包(含 bin、lib)
常见坑
| 现象 | 原因 | 处理 |
|---|---|---|
Unknown lifecycle phase ".test.skip=true" |
PowerShell 把 -D 拆开了 |
写成 "-Dmaven.test.skip=true" |
| 父 POM / 依赖找不到 | 未连内网或 Nexus 不可达 | 连 VPN,确认 .mvn/settings.xml |
spring-boot-maven-plugin 报错 |
Maven 版本或插件依赖问题 | 使用 mvnw,不要混用过旧 Maven |
七、package 不会启动服务
重要:mvn clean package 只编译打包,不会启动 Spring Boot 进程。
如果执行 package 后访问 http://localhost:8080/health 仍有响应,通常是:
- 本机已有旧进程在跑 (例如 IDE 之前启动的
Application) - 8080 被其他项目占用 (需用
netstat确认 PID 和主类)
验证方式:
powershell
netstat -ano | findstr "LISTENING" | findstr "808"
确认监听 8080 的进程是否真的是 com.allawn.crypto.provider.Application。
八、本地启动
前置条件
- JDK 11+
- 公司内网 / VPN(Heracles、Euler 注册中心、Nexus)
crypto-auth-provider-impl/conf/目录存在(本地配置,通常不进 git)
方式一:IDE(推荐调试)
-
主类:
com.allawn.crypto.provider.Application -
Working directory:
crypto-auth-provider-impl -
VM options 建议:
ini-Dloader.path=conf -Dheracles.bootstrap.enabled=true -Ddubbo.consumer.check=falsedubbo.consumer.check=false表示下游crypto-key-dist-provider不在线时也能先启动(真正调签名接口时仍会依赖它)。
方式二:Maven 启动
powershell
.\mvnw.cmd -pl crypto-auth-provider-impl spring-boot:run "-Dmaven.test.skip=true" "-Dspring-boot.run.jvmArguments=-Dloader.path=conf -Ddubbo.consumer.check=false"
方式三:jar 启动
powershell
cd crypto-auth-provider-impl
java -Dloader.path=conf -Dheracles.bootstrap.enabled=true -jar target\crypto-auth-provider.jar
验证
powershell
curl http://localhost:8080/health
# 期望返回:OK
签名接口示例见 crypto-auth-provider-impl/http/sign.http。
端口说明
| 服务 | 默认端口 |
|---|---|
| HTTP | 8080 (application.properties 中 server.port) |
| Dubbo | 20880 |
| Dubbo QoS 诊断 | 22222 (http://localhost:22222/ls) |
九、速查卡片
powershell
# 构建
.\mvnw.cmd clean package "-Dmaven.test.skip=true"
# 发布到 Nexus(通常仅 api 模块;impl 已 deploy.skip)
.\mvnw.cmd deploy -pl crypto-auth-provider-api
# 启动(Maven)
.\mvnw.cmd -pl crypto-auth-provider-impl spring-boot:run "-Dmaven.test.skip=true" "-Dspring-boot.run.jvmArguments=-Dloader.path=conf -Ddubbo.consumer.check=false"
# 健康检查
curl http://localhost:8080/health
# 看谁占了端口
netstat -ano | findstr ":8080"