4. SDK 获取与引入:Maven / Gradle / NPM 坐标与本地 JAR 引入

好了,到了真正动手的环节。SDK 拿不到手上,后面全是白搭。这一章我帮你把获取 SDK 的几种主流方式掰开揉碎讲清楚,顺便聊聊我在实际项目中踩过的那些坑。

4.1 先搞清楚你用哪种构建工具

你想想看,团队用 Maven 还是 Gradle,前端用 NPM 还是 Yarn,这直接决定了你该怎么写依赖坐标。下面这个表格我整理了三类常见场景的坐标写法,你可以直接 Ctrl+C 拿回去用。

构建工具 适用范围 坐标格式示例(审计 SDK v2.1.0) 备注
Maven Java 后端项目 com.example:audit-sdk:2.1.0 默认中央仓库,私服需配置 settings.xml
Gradle Java / Kotlin / Android implementation 'com.example:audit-sdk:2.1.0' Kotlin DSL 写法类似
NPM Node.js 前端 / 服务端 "@example/audit-sdk": "^2.1.0" 建议锁定大版本,语义化版本控制
小技巧:我个人习惯在项目初期就把依赖版本号提取到 properties 或 ext 块里,方便统一升级。比如 Maven 用 <properties>,Gradle 用 ext,别让版本号满天飞。

4.2 Maven 坐标:写在 pom.xml 的注意事项

Maven 用户最多,坑也最多。我先给你一个标准片段,再说说容易翻车的地方。

<dependency>
    <groupId>com.example</groupId>
    <artifactId>audit-sdk</artifactId>
    <version>2.1.0</version>
    <scope>compile</scope>
</dependency>

嗯,这里要注意 scope。默认就是 compile,你一般不用写。但如果你只是做本地开发测试,不想把 SDK 带进生产包,可以用 <scope>test</scope>。不过审计 SDK 通常是运行时必备,我不建议改 scope。

曾经我遇到过:同事把 SDK 依赖写成了 provided 作用域,结果部署到容器里一直报 ClassNotFoundException。排查了三个小时,最后发现是 scope 写错了。记住:审计 SDK 除非你只在编译期使用接口,否则别动 scope。

4.3 Gradle 坐标:implementation vs api 之争

Gradle 用户注意,推荐用 implementation 而不是 api。为什么呢?说白了,implementation 能让编译速度更快,而且不会把依赖泄露给消费者。如果你只是在自己的模块里用审计 SDK,implementation 完全够用。

dependencies {
    implementation 'com.example:audit-sdk:2.1.0'
}

但如果你写的是公共库(比如公司内部的审计工具包),其他模块需要直接引用 SDK 中的类,那就得用 api。这个选择我建议你在项目初期就定好,不然后面改起来很蛋疼。

4.4 NPM 坐标:语义化版本与锁文件

前端同学看过来。NPM 包引入很简单,但版本号写法有讲究。我推荐用 ^ 来锁定大版本,同时配合 package-lock.json 或 yarn.lock 锁死具体版本。

// package.json
{
  "dependencies": {
    "@example/audit-sdk": "^2.1.0"
  }
}

为什么?因为有次我项目里用了 ~2.1.0,结果 CI 环境自动下载了 2.1.6,小版本升级引入了破坏性改动,审计记录格式变了,导致下游解析全挂。从那以后,我所有生产项目都保留了 lock 文件,并且版本号只用 ^。

4.5 本地 JAR 引入:企业内网的终极方案

有些团队走不了外网,或者内部私有仓库还没搭建好,那就只能手动放 JAR 了。这里我分 Java 和前端两种情况说。

4.5.1 Java 项目:lib 目录 + 系统依赖

老项目经常这么干。你在项目根目录建一个 lib 文件夹,把 audit-sdk-2.1.0.jar 扔进去,然后这样配置:

Maven 方式:

<dependency>
    <groupId>com.example</groupId>
    <artifactId>audit-sdk</artifactId>
    <version>2.1.0</version>
    <scope>system</scope>
    <systemPath>${project.basedir}/lib/audit-sdk-2.1.0.jar</systemPath>
</dependency>

Gradle 方式:

dependencies {
    implementation files('lib/audit-sdk-2.1.0.jar')
}
警告:Maven 的 system 作用域不推荐在生产使用,因为打包时它默认不会把 JAR 包进去。我见过有人用 system 然后 mvn package 出来的 war 里找不到 SDK,部署就挂了。如果你非得用本地引入,建议配合 maven-install-plugin 把 JAR 装进本地仓库,或者用 Gradle 的 flatDir 仓库。

4.5.2 前端项目:直接复制到项目中

前端其实更简单。直接把 audit-sdk.min.js 放到 src/lib/ 目录,然后在入口文件里 import:

import AuditSDK from '@/lib/audit-sdk.min.js';

但这么做有弊端:无法自动更新版本。我一般只在临时测试或外网不通时用,正式环境还是建议走 NPM 私有仓库。

4.6 获取 SDK 的完整决策流程

下面这张图是我自己画的一个决策树,帮你在不同场景下快速选择方案。嗯,直接看 SVG 吧。

SDK 获取方式决策流程 能访问外网? 是 → 使用包管理坐标 否 → 考虑本地 JAR 引入 Java / 后端 Node / 前端 Maven Gradle NPM 本地 JAR 目录 手写 systemPath flatDir / files() 实际项目中建议优先使用包管理坐标,本地引入仅作为临时或内网方案

看到这张图,你心里应该有个谱了。我再补充一点:如果你公司有私有仓库(Nexus、Artifactory),优先用它发布 SDK,然后 pom.xml 里指向私服地址,这样团队所有人都能统一拉取。

4.7 关于版本选择的个人建议

我在项目里见过太多人追求“最新版”。其实审计 SDK 这种基础设施,稳定压倒一切。我的做法是:

  1. 先看 release notes,确认没有行为变更。
  2. 在测试环境跑一遍全量回归。
  3. 确认没问题了才升级生产。
  4. 如果用的是 NPM,^ 号可以放心用,但 lock 文件必须提交。
核心原则:SDK 引入方式不重要,重要的是版本一致性和可追溯性。不管你选哪种方式,项目里所有开发人员拉到的 SDK 必须是同一个版本,不然审计记录格式对不上,排查起来非常痛苦。