把内容存成节点树而不建文章表:Java 内容仓库标准 JCR 讲了什么
同一个 Java CMS 圈子里,有两拨人聊不到一起。
AEM 的实施商开口闭口 JCR、Oak、Sling,聊内容先聊"节点类型"和工作区;Halo 的用户论坛里,这些词出现的频率约等于零,大家聊的是主题、插件和自定义模型。
分界线出在内容怎么存。把这套词汇拆开看一遍,Java CMS 的族谱就顺了;哪怕最后选的是 Halo,知道自己不用碰哪套东西也省心。
是什么:把内容存成节点树
JCR 全称 Java Content Repository,是 J2EE 时代由瑞士 Day Software(后来被 Adobe 收购、产品变成 AEM 的那家公司)的首席技术官 David Nuescheler 牵头制定的标准。1.0 版 JSR-170 在 2005 年 5 月定稿,2.0 版 JSR-283 在 2009 年 8 月发布。
它干的核心事,是像 JDBC 统一关系库接口那样,给"内容仓库"定一套标准 Java 接口(javax.jcr.*),并且把内容抽象成一棵带类型的树:一个仓库分成多个工作区(Workspace),比如 Magnolia 默认把网页放在 website、系统配置放在 config、用户放在 users,各自是一棵树;树上的节点(Node)有路径和节点类型,底下挂存具体值的属性(Property)或子节点。
当年企业愿意买账,还因为它顺带揽下了两件重活:
- 底层存储位置对应用透明:底下最终落进 MySQL、PostgreSQL、MongoDB 还是本地文件,由仓库的持久化层(Persistence Manager 或 NodeStore)去管,上层业务代码只管调 JCR API 读写节点。
- 把内容系统常造的轮子收进规范层:版本历史、节点锁定、细粒度访问控制、观察事件监听、结构化查询(JCR-SQL2)和整棵子树的 XML 导入导出,标准里直接带了一套。
拿国内常见的两款轻量产品对比着看更直观:JPress 这类传统建站系统,文章就是 MySQL 里的表,一行一篇,走主键和 SQL 增删改查;Halo 2.x 换成了反应式架构,用 R2DBC 连库,把文章、分类、页面统一抽象成带版本与分组标识的 Extension 自定义模型。但不管是一张表还是一份自定义模型,它们都是按条存的记录;JCR 则是把页面、区域、组件和配置全挂在同一棵树上,按路径一层层往下找。两边应付的本就不是同一种场面。
两个 Apache 项目撑起这一层
Apache Jackrabbit 是 JCR 的官方参考实现,由 Day Software 把初始实现捐给 Apache 基金会孵化而来,2006 年成为顶级项目,Magnolia 至今用的还是 Jackrabbit 2.x 系列。后来大客户的内容树动辄上千万节点,单机树结构在高并发下成了瓶颈,Adobe 收购 Day Software 后主导重写了下一代内核 Jackrabbit Oak——它把存储抽象成 NodeStore,单机跑本地 tar 文件(SegmentNodeStore),集群则把节点存进 MongoDB 或关系型数据库(DocumentNodeStore),从 AEM 6.0 起成了默认底座。
Apache Sling 架在 JCR 仓库之上做 Web 映射,同样出自 Day Software。它把浏览器请求的 URL 路径直接拆解并映射成 JCR 树上的节点路径,再顺着节点上的 sling:resourceType 属性找到对应的脚本把页面渲染出来。写 Sling 应用的思路接近"先在树里放好节点,网址自然就有了",和 Spring MVC 先写控制器路由是两套路子。
Jackrabbit(含 Oak)和 Sling 都是 Apache 顶级项目,采用 Apache-2.0 协议,至今仍在持续发版。
谁踩在这层上面
商业化最成功的那套是 Adobe Experience Manager(AEM)。正篇(一)和正篇(三)都提过它,AEM 的官方文档写得很直接:整套系统建在 Apache Sling、Apache Jackrabbit Oak 和 OSGi 容器之上,浏览器进来的请求先由 Sling 接住,再落到 Oak 管理的 JCR 节点树里读写。
开源阵营里的代表是 Magnolia。官方架构文档写明它是第一个专门围绕 JCR 构建的开源 CMS,不论是 GPL v3 的社区版还是商业版 DX Core,底层跑的都是 Apache Jackrabbit(2.x 系列),官方认证栈文档也把 Magnolia DX Core 与 Apache Jackrabbit JCR 并列标为兼容测试的基准。选 Magnolia 做二次开发,JCR 是绕不开的地基——内容模型怎么定、工作区怎么分、甚至配个系统参数,都是在跟这棵树打交道(本系列番外二算内存账、番外六看 Headless 接口时,Magnolia 身上的脾气也全从这棵树上来)。
而轻量那一档的 Halo 和 JPress 完全不碰 JCR。个人博客、知识库和中小企业官网用不着在一篇文章底下套五层组件节点,直接查表或调 Extension 接口,心智负担小得多。
你会不会撞上它:三个信号
判断自己要不要花时间啃 JCR,看手头有没有这三个信号:
- 选型备选单里列着 Magnolia、Jahia、Bloomreach,或者公司正在评估 AEM 实施商的方案;
- 业务需求里明确要求"页面下面套区域、区域下面套组件、整棵栏目树导出成 YAML/XML 跨环境同步"这类深层树状内容管理;
- 团队招人或对接外部接口时,对方已经在提"JCR 工作区"“节点类型”"Persistence Manager"这些词。
三条全没占,那 Halo、JPress 乃至常规的 Spring Boot 建站系统就够用了,一辈子不用去翻 JSR-283 规范。只要占了一条,就得先把"数据库里有表却不能直接拿 SQL SELECT 改文章"这件事接受下来——因为 Jackrabbit 落进 MySQL 或 PostgreSQL 里的是序列化后的节点 Bundle,所有读写都必须守规矩走 JCR API 或系统放出来的 REST / GraphQL 接口。正篇(三)说对 Sling 和 Oak 的建议是"理解它,然后不自己造",讲的就是这层门槛。
认清自己的内容到底该按记录存成表,还是按层级挂成树,Java CMS 里那两拨人的黑话就都听得懂了。
- 点赞
- 收藏
- 关注作者
评论(0)