Apache Commons JCS 3.2.1 常用 API 与工具详解
梳理 Apache Commons JCS 3.2.1 常用 API——JCS 工厂、CacheAccess 读写、统计与命中率、生命周期管理——及 Maven/javap/java 工具命令,每条命令附真实回显。
Apache Commons JCS 3.2.1 常用 API 与工具详解
目标:系统梳理 Apache Commons JCS 3.2.1 的常用编程 API(JCS 入口工厂、CacheAccess 数据读写、统计与命中率、生命周期管理)与配套工具命令(Maven dependency 系列、javap、java -cp),每条命令与签名均以实测回显佐证。以下全部命令与回显均已在 Ubuntu 22.04(x86_64)实测通过。
一、环境信息
本节固定实测基线,所有 API 调用与工具命令均基于同一工程验证。
- 操作系统:Ubuntu 22.04(x86_64)
- JDK:OpenJDK 17.0.20.1
- 构建工具:Apache Maven 3.6.3
- 目标库:Apache Commons JCS 3.2.1(
org.apache.commons:commons-jcs3-core:3.2.1) - 示例工程目录:
/opt/jcs-demo - 配置文件:
/opt/jcs-demo/conf/cache.ccf(磁盘区域diskRegion,逐项详解见《Apache Commons JCS 3.2.1 配置参数详解》) - 运行时 classpath 文件:
/opt/jcs-demo/cp.txt(内容仅 core jar 一行) - 核心 jar:
/root/.m2/repository/org/apache/commons/commons-jcs3-core/3.2.1/commons-jcs3-core-3.2.1.jar - 磁盘缓存数据目录:
/opt/jcs-demo/disk-cache
Commons JCS 没有命令行 CLI 工具——它是进程内库,本文的「工具」指围绕它的 API 检查(javap)、依赖管理(mvn dependency 系列)与运行(java -cp)命令。
二、工具概览
使用 JCS 前先建立 API 与工具的全景认知:编程层面只有 2 个核心入口类 + 1 个统计接口;工具层面 3 类命令覆盖依赖、反查与运行。
| 类别 | 名称 | 作用 | 本文对应章节 |
|---|---|---|---|
| API | org.apache.commons.jcs3.JCS | 静态工厂,按区域名获取缓存访问器 | 4.1 |
| API | org.apache.commons.jcs3.access.CacheAccess<K, V> | put/get/getMatching/remove/clear/dispose 等数据操作 | 4.2 |
| API | ICacheStats / getStats() | 命中率与缓存规模统计 | 4.3 |
| API | JCS.shutdown() / dispose() | 缓存管理器与区域生命周期控制 | 4.4 |
| 工具 | mvn dependency:get/tree/list/build-classpath | 构件预下载、依赖树、版本确认、classpath 生成 | 5.1–5.4 |
| 工具 | javap | 反查 jar 中 API 签名(离线 API 手册) | 5.5 |
| 工具 | java -cp | 直接运行编译好的类 | 5.6 |
💡 技术拓展:使用 JCS 时有三种可选的编程接口风格——
接口风格 说明 特点 适用场景 JCS 原生 API(本文实测) JCS.getInstance+CacheAccess最直接,区域/属性/统计全开放 JCS 深度集成(本文实测采用) JCache 标准 API(JSR-107) 官方 commons-jcs-jcache模块提供实现标准注解与接口,可平滑换实现 需要标准化的多缓存后端架构 Spring Cache 抽象 框架层 @Cacheable体系声明式缓存,业务零侵入 Spring 技术栈 本文实测采用 JCS 原生 API:官方 dist 发行包同时包含 commons-jcs-core 与 commons-jcs-jcache 模块(《Ubuntu 22.04 安装 Apache Commons JCS 指南》5.3 目录结构实测可证),但原生 API 无额外抽象层、统计信息最完整,适合本文的讲解与排障定位。
三、前置条件
API 验证需要工程与运行环境就绪,逐项确认。
- 工程已引入
commons-jcs3-core:3.2.1并编译通过(工程搭建见《Ubuntu 22.04 安装 Apache Commons JCS 指南》第四章,此处复用同一目录),版本确认:
cd /opt/jcs-demo && mvn -B dependency:list 2>&1 | grep "commons-jcs3-core"
输出:
[INFO] org.apache.commons:commons-jcs3-core:jar:3.2.1:compile
[INFO] BUILD SUCCESS
- 运行时 classpath 文件已生成(仅 core jar,无传递依赖):
cd /opt/jcs-demo && cat cp.txt
输出:
/root/.m2/repository/org/apache/commons/commons-jcs3-core/3.2.1/commons-jcs3-core-3.2.1.jar
conf/cache.ccf已就位(classpath 无该文件时启动直接 NPE,复现回显见《Ubuntu 22.04 安装 Apache Commons JCS 指南》4.6 节)。
💡 说明:下文演示程序
demo.BasicCacheDemo(内存读写与统计)与demo.DiskCacheDemo(磁盘缓存 put/get 双模式)的完整源码见《Ubuntu 22.04 安装 Apache Commons JCS 指南》4.4 节,本文直接使用其运行回显。
四、核心 API 详解
4.1 JCS 入口工厂:getInstance 三种重载
做什么:JCS 是绝大多数场景唯一的入口类,静态方法 getInstance(regionName) 返回区域访问器;区域不存在时按默认属性即时创建(回显见《CentOS 8 安装 Apache Commons JCS 指南》4.6 节 Parsed regions [] 后动态构造 centosRegion)。用 javap 离线反查其全部重载签名(cp.txt 内容即核心 jar 路径):
javap -cp $(cat /opt/jcs-demo/cp.txt) org.apache.commons.jcs3.JCS | grep getInstance
输出:
public static <K, V> org.apache.commons.jcs3.access.CacheAccess<K, V> getInstance(java.lang.String) throws org.apache.commons.jcs3.access.exception.CacheException;
public static <K, V> org.apache.commons.jcs3.access.CacheAccess<K, V> getInstance(java.lang.String, org.apache.commons.jcs3.engine.behavior.ICompositeCacheAttributes) throws org.apache.commons.jcs3.access.exception.CacheException;
public static <K, V> org.apache.commons.jcs3.access.CacheAccess<K, V> getInstance(java.lang.String, org.apache.commons.jcs3.engine.behavior.ICompositeCacheAttributes, org.apache.commons.jcs3.engine.behavior.IElementAttributes) throws org.apache.commons.jcs3.access.exception.CacheException;
逐项解读:三个重载按「配置粒度」递进——① 只给区域名,属性走 cache.ccf 或默认值(本文全部演示用此形态);② 额外传 ICompositeCacheAttributes 覆盖区域级属性(如 MaxObjects);③ 再传 IElementAttributes 覆盖条目级属性(如过期时间)。三者的返回类型均为泛型 CacheAccess<K, V>,且都声明抛出 CacheException(配置非法或创建失败时)。
4.2 CacheAccess:数据读写与删除
做什么:CacheAccess<K, V> 是区域上的操作句柄,覆盖单条读写、模式匹配批量读、删除与清空。CacheAccess 接口定义了 put/get/remove/getMatching,其继承链上的 AbstractCacheAccess 实现了 clear/统计/dispose,两条 javap 分别反查(classpath 即 cp.txt 中的核心 jar):
javap -cp /root/.m2/repository/org/apache/commons/commons-jcs3-core/3.2.1/commons-jcs3-core-3.2.1.jar org.apache.commons.jcs3.access.CacheAccess | grep -E "put|get\(|remove"
javap -cp /root/.m2/repository/org/apache/commons/commons-jcs3-core/3.2.1/commons-jcs3-core-3.2.1.jar org.apache.commons.jcs3.access.AbstractCacheAccess | grep -E "clear|getStatistics|getStats|dispose"
输出:
public V get(K);
public java.util.Map<K, V> getMatching(java.lang.String);
public void put(K, V);
public void put(K, V, org.apache.commons.jcs3.engine.behavior.IElementAttributes);
public void remove(K);
public void clear() throws org.apache.commons.jcs3.access.exception.CacheException;
public org.apache.commons.jcs3.engine.stats.behavior.ICacheStats getStatistics();
public java.lang.String getStats();
public void dispose();
实测这些签名(demo.BasicCacheDemo 的 put/get/remove 段,运行回显):
[put] k1..k3
[get] 5 次 (3 命中 2 未命中)
get(k1) = value-1
get(k2) = value-2
get(k3) = value-3
get(k4) = null
get(k5) = null
[remove] k1
get(k1) after remove = null
逐项解读:put(K, V) 写入即参与统计(Put Count);get 未命中返回 null 而非抛异常,调用方需判空;remove(k1) 后再 get 返回 null 且计入 Miss Count(统计见 4.3);put 的第二个重载可对单条指定元素属性(如只对这条设过期),与区域默认属性并存。getMatching(String pattern) 按 key 前缀/模式批量取回一个 Map<K, V>,适合按业务前缀分组管理的数据(其行为本文未实测,签名以 javap 回显为准)。
4.3 统计与命中率:getStatistics 与 getStats
做什么:JCS 内置两级统计——getStatistics() 返回结构化 ICacheStats(程序可解析),getStats() 返回多行文本(人读)。实测(demo.BasicCacheDemo,运行回显):
[statistics]
type = null
HitCountRam = 3
HitCountAux = 0
getStats() = Region Name = demoRegion
HitCountRam = 3
HitCountAux = 0
---------------------------Memory Cache
Put Count = 3
Hit Count = 3
Miss Count = 3
Map Size = 2
List Size = 2
统计口径逐项解读(对照程序动作:put 3 条 → get k1..k5 → remove k1 → get k1):
HitCountRam = 3:内存层命中 k1/k2/k3 三次;HitCountAux = 0:辅助缓存命中为 0(demoRegion未绑定磁盘等辅助缓存;diskRegion场景下命中会落在 Aux)。Put Count = 3:put 三条;Hit Count = 3与Miss Count = 3:内存层 5 次 get 命中 3 次 + remove 后 get k1 未命中 1 次,加上初始 k4/k5 两次未命中,共 3 次未命中。Map Size = 2:remove k1 后内存剩 k2/k3;List Size = 2:LRU 链表节点数与之一致。type = null:该版本ICacheStats.getTypeName()对内存区域返回 null,属实测事实而非异常。clear后再 get:Miss Count增至 4、Map Size = 0(完整前后对照回显见《Ubuntu 22.04 安装 Apache Commons JCS 指南》4.6 节)。
命中率可由口径直接计算:命中率 = Hit Count / (Hit Count + Miss Count)。程序化解析用 getStatistics()(本例打出的元素即 IStatElement 列表),人看趋势用 getStats() 文本。
4.4 生命周期:clear、dispose 与 JCS.shutdown
做什么:三类「关闭」语义不同——clear() 只清数据不清区域;dispose() 释放单个区域(磁盘区域此时把内存剩余条目刷盘并保存键索引);JCS.shutdown() 关闭整个缓存管理器。磁盘区域的 dispose 实测回显(demo.DiskCacheDemo put,完整回显见《Apache Commons JCS 3.2.1 配置参数详解》5.6 节):
Oct 14, 2026 10:27:28 AM org.apache.commons.jcs3.engine.control.CompositeCache
INFO: In DISPOSE, [diskRegion] fromRemote [false]
Oct 14, 2026 10:27:28 AM org.apache.commons.jcs3.engine.control.event.ElementEventQueue
INFO: Element event queue destroyed: org.apache.commons.jcs3.engine.control.event.ElementEventQueue@27f723
Oct 14, 2026 10:27:28 AM org.apache.commons.jcs3.engine.control.CompositeCache
INFO: In DISPOSE, [diskRegion] auxiliary [diskRegion]
Oct 14, 2026 10:27:28 AM org.apache.commons.jcs3.engine.control.CompositeCache
INFO: In DISPOSE, [diskRegion] put 9 into auxiliary [diskRegion]
Oct 14, 2026 10:27:28 AM org.apache.commons.jcs3.auxiliary.disk.AbstractDiskCache
INFO: In dispose, destroying event queue.
Oct 14, 2026 10:27:28 AM org.apache.commons.jcs3.engine.PooledCacheEventQueue
INFO: Cache event queue destroyed: CacheEventQueue [listenerId=972252816, cacheName=diskRegion]
Oct 14, 2026 10:27:28 AM org.apache.commons.jcs3.auxiliary.disk.indexed.IndexedDiskCache
INFO: Region [diskRegion] : Saving keys to: diskRegion, key count: 20
Oct 14, 2026 10:27:28 AM org.apache.commons.jcs3.auxiliary.disk.indexed.IndexedDiskCache
INFO: Region [diskRegion] : Finished saving keys.
Oct 14, 2026 10:27:28 AM org.apache.commons.jcs3.auxiliary.disk.indexed.IndexedDiskCache
INFO: Region [diskRegion] : Shutdown complete.
cache.dispose() 之后程序又调用了 JCS.shutdown(),管理器关闭会对各区域再次触发 dispose,对已关闭的磁盘缓存打出实测到的 SEVERE 记录(同一进程、done 前的最后日志):
Oct 14, 2026 10:27:28 AM org.apache.commons.jcs3.engine.control.CompositeCache
INFO: In DISPOSE, [diskRegion] disposing of memory cache.
Oct 14, 2026 10:27:28 AM org.apache.commons.jcs3.engine.memory.AbstractMemoryCache
INFO: Memory Cache dispose called.
Oct 14, 2026 10:27:28 AM org.apache.commons.jcs3.auxiliary.disk.AbstractDiskCache
INFO: In dispose, destroying event queue.
Oct 14, 2026 10:27:28 AM org.apache.commons.jcs3.auxiliary.disk.indexed.IndexedDiskCache
SEVERE: Region [diskRegion] : Not alive and dispose was called, filename: diskRegion
解读与最佳实践:磁盘区域的「持久化三步」是 dispose()(put 9 into auxiliary 刷内存残条 + Saving keys to: diskRegion, key count: 20 写索引,Shutdown complete. 收尾)→ JCS.shutdown()(关管理器,实测会对已 dispose 区域产生上述 SEVERE 记录,但进程正常退出)→ 进程退出;新进程启动时加载索引(Loaded keys from [diskRegion], key count: 20,读回 20/20 实测见《Apache Commons JCS 3.2.1 快速入门与集成示例》第六章)。另有兜底机制:主线程未显式 shutdown 时,JCS 的 Shutdown 钩子会在 JVM 退出阶段自动关闭(Shutdown hook activated. Shutdown was not called. Shutting down JCS.,实测见《CentOS 8 安装 Apache Commons JCS 指南》4.6 节末行)——但依赖钩子不如显式调用可靠。
五、Maven 与 JDK 工具命令
5.1 mvn dependency:get:预下载构件
做什么:不建工程直接把指定坐标构件拉入本地仓库,适合内网预热与离线分发的第一步:
cd /opt/jcs-demo && mvn -B dependency:get -Dartifact=org.apache.commons:commons-jcs3-core:3.2.1
输出节选(实测末尾 12 行):
[INFO] Downloaded from central: https://repo.maven.apache.org/maven2/org/apache/commons/commons-jcs3-core/3.2.1/commons-jcs3-core-3.2.1.jar (547 kB at 37 kB/s)
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 02:54 min
[INFO] Finished at: 2026-10-14T10:22:06Z
[INFO] ------------------------------------------------------------------------
💡 说明:下载日志中出现的 junit/hamcrest/hsqldb 等是 JCS POM 里非 compile 范围的声明,不会进入运行时 classpath(判定见 5.2/5.4)。
5.2 mvn dependency:tree:查看依赖树
做什么:打印工程依赖树,验证「JCS 无传递依赖」:
cd /opt/jcs-demo && mvn -B dependency:tree
输出节选(实测):
[INFO] --- maven-dependency-plugin:2.8:tree (default-cli) @ jcs-demo ---
[INFO] demo:jcs-demo:jar:1.0.0
[INFO] \- org.apache.commons:commons-jcs3-core:jar:3.2.1:compile
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------
解读:树中只有 core 自身一个 compile 节点——离线部署仅需拷贝这一个 jar。
5.3 mvn dependency:list:确认解析版本
做什么:列出 Maven 实际解析的依赖坐标与版本,排查「引错版本」:
cd /opt/jcs-demo && mvn -B dependency:list 2>&1 | grep "commons-jcs3-core"
输出:
[INFO] org.apache.commons:commons-jcs3-core:jar:3.2.1:compile
[INFO] BUILD SUCCESS
5.4 mvn dependency:build-classpath:生成运行时 classpath
做什么:把运行时 classpath 写入文件,供 java -cp 组合使用:
cd /opt/jcs-demo && mvn -B dependency:build-classpath -Dmdep.outputFile=/opt/jcs-demo/cp.txt 2>&1 | tail -3
cat cp.txt
输出:
[INFO] Total time: 0.738 s
[INFO] Finished at: 2026-10-14T10:24:52Z
[INFO] ------------------------------------------------------------------------
/root/.m2/repository/org/apache/commons/commons-jcs3-core/3.2.1/commons-jcs3-core-3.2.1.jar
验证点:文件只有一行 core jar,与 5.2 的依赖树结论互相印证。
5.5 javap:离线反查 API 签名
做什么:JDK 自带的类文件反汇编工具,不需要联网查文档即可确认某版本 jar 的真实 API(4.1/4.2 的两条签名即出自 javap)。基础用法回顾:
javap -cp /root/.m2/repository/org/apache/commons/commons-jcs3-core/3.2.1/commons-jcs3-core-3.2.1.jar org.apache.commons.jcs3.JCS | grep getInstance
输出:
public static <K, V> org.apache.commons.jcs3.access.CacheAccess<K, V> getInstance(java.lang.String) throws org.apache.commons.jcs3.access.exception.CacheException;
public static <K, V> org.apache.commons.jcs3.access.CacheAccess<K, V> getInstance(java.lang.String, org.apache.commons.jcs3.engine.behavior.ICompositeCacheAttributes) throws org.apache.commons.jcs3.access.exception.CacheException;
public static <K, V> org.apache.commons.jcs3.access.CacheAccess<K, V> getInstance(java.lang.String, org.apache.commons.jcs3.engine.behavior.ICompositeCacheAttributes, org.apache.commons.jcs3.engine.behavior.IElementAttributes) throws org.apache.commons.jcs3.access.exception.CacheException;
解读:-cp 指向 jar 即可反查其内任意全限定类名;grep 过滤关注方法。发行包还自带 sources/javadoc jar(《Ubuntu 22.04 安装 Apache Commons JCS 指南》5.3 目录实测含 commons-jcs3-core-3.2.1-sources.jar 与 -javadoc.jar),可与 javap 互为补充。
5.6 java -cp:组装 classpath 运行
做什么:脱离 IDE 直接运行编译产物,是生产排障的常用形态。典型命令(两个演示程序的运行入口):
cd /opt/jcs-demo && java -Dfile.encoding=UTF-8 -cp target/classes:conf:$(cat cp.txt) demo.BasicCacheDemo
cd /opt/jcs-demo && java -Dfile.encoding=UTF-8 -cp target/classes:conf:$(cat cp.txt) demo.DiskCacheDemo put
输出(第一条命令的完整回显见《Ubuntu 22.04 安装 Apache Commons JCS 指南》4.6 节;第二条见《Apache Commons JCS 3.2.1 配置参数详解》5.6 节,此处摘程序输出行):
put 完成: disk-key-1..20
get(disk-key-7) = disk-value-7
done
逐项解读:-cp 依次是编译产物 target/classes、配置目录 conf(提供 classpath 资源 cache.ccf)、由 $(cat cp.txt) 展开的依赖 jar;-Dfile.encoding=UTF-8 因系统默认编码为 ANSI_X3.4-1968 而必须(否则中文输出乱码)。两个 demo 均以 done 结束。
六、注意事项
- 先有配置再 getInstance:classpath 无
cache.ccf时 3.2.1 直接 NPE(回显见《Ubuntu 22.04 安装 Apache Commons JCS 指南》4.6 节),不是警告。 - get 返回 null 不是异常:未命中返回 null,调用方必须判空;
clear()声明抛CacheException(javap 签名可见),而 get/put/remove 不声明受检异常。 - 统计是分层的:
HitCountRam只计内存层,HitCountAux只计辅助缓存层;绑定磁盘的区域命中可能落在 Aux,勿只看 Ram 判命中率。 - 磁盘区域必须善后:持久化依赖 dispose 阶段的
Saving keys(4.4 实测),强杀进程会丢索引更新;dispose 后复用访问器会产生 SEVERE 级数据丢失告警。 - 编码:默认编码为 POSIX/ASCII 的环境一律加
-Dfile.encoding=UTF-8。 - 版本排查:出现 API 不存在等诡异问题时,先
dependency:list确认实际解析版本(5.3),再用 javap 对照签名(5.5)。
七、常见问题(FAQ)
Q1:JCS.getInstance 抛 NPE(inStream parameter is null)?
不是 API 问题:classpath 上缺 cache.ccf(完整栈见《Ubuntu 22.04 安装 Apache Commons JCS 指南》4.6 节)。补配置或把 conf 目录加入 -cp。
Q2:javap 报「找不到类」?
-cp 必须指向包含该类的 jar(本文为核心 jar 的绝对路径)且类名用全限定名(如 org.apache.commons.jcs3.JCS);先 cat cp.txt 确认 jar 路径存在。
Q3:getStats() 文本里没有辅助缓存段?
文本统计按「区域实际绑定的辅助缓存」输出:未绑定磁盘的区域(如 demoRegion)只有 Memory Cache 段(4.3 回显);diskRegion 绑定 DC 后其命中计入 HitCountAux。
Q4:dispose() 后进程日志出现 SEVERE: Region [diskRegion] : Not alive and dispose was called, filename: diskRegion?
实测(4.4):演示程序按 cache.dispose() → JCS.shutdown() 顺序关闭,shutdown 对已关闭的区域再次触发 dispose 时打出该 SEVERE 记录,进程仍以 done 正常退出,属实测关闭序列的一部分;数据已由 dispose 阶段落盘(Saving keys)。若想消除该记录,可实测仅调用 JCS.shutdown() 的形态(本文未实测)。
Q5:进程退出打出 Shutdown hook activated. Shutdown was not called. Shutting down JCS.?
未显式调用 JCS.shutdown() 时钩子兜底关闭(实测见《CentOS 8 安装 Apache Commons JCS 指南》4.6 节末行)。功能无损但建议显式管理生命周期,尤其磁盘区域需要可靠的落盘时机。
Q6:依赖里有 junit/hsqldb,离线服务器要补这些 jar 吗?
不用。它们是 POM 中非 compile 范围声明,dependency:tree 与 build-classpath(5.2/5.4 实测)均证明运行时只需 core jar。
八、参考链接
- Apache Commons JCS 官方站点(Javadoc 入口):https://commons.apache.org/proper/commons-jcs/
- Maven 中央仓库坐标页:https://repo1.maven.org/maven2/org/apache/commons/commons-jcs3-core/
- 源码仓库(GitHub 镜像):https://github.com/apache/commons-jcs
- JDK javap 工具手册:https://docs.oracle.com/en/java/javase/17/docs/specs/man/javap.html
- 本文配套:《Apache Commons JCS 3.2.1 配置参数详解》《Apache Commons JCS 3.2.1 快速入门与集成示例》