当前位置: 首页 > 工具软件 > eXo JCR > 使用案例 >

JCR集成Java内容仓库和Spring

朱令
2023-12-01

保存各种信息对于应用程序来说非常平常,大多数时候它们是保存在关系数据库中。数据库处理规范数据类型十分在行,但是在处理如图像、文档等二进制数据时却不是那么得心应手。尽管可以用文件系统作为替代——而且它们还提供了更好的性能。但它们既没有提供用于搜索信息的查询语言,也没有提供表示关系或事务的概念。
在很多情况下,允许第三方访问这些存储数据(随着应用程序的不断扩展,这成为一个典型的需求)是一个漫长而复杂的过程(它们不会在一夜之间完成)。内部存储结构很容易影响API架构,以及信息检索与遍历的方式。
什么是JSR-170幸运的是,被称为Java内容仓库(Java Content Repository,JCR)的JSR-170,试图以独立于具体实现的方式解决这些(以及其它)问题。即,不论底层资源(如,数据库,本地或虚拟文件系统)是什么,API都将相同。在数据存储之上,JCR提供诸如访问粒度控制、版本控制、内容事件、全文检索和过滤等内容服务。由Day Software领导的JSR-170背后的专家组令人印象深刻,包括内容管理系统(CMS)提供商Vignette、Hummingbird Ltd.、Stellent和通用Java驱动解决方案提供商,如BEA Systems、IBM和Oracle。该规范很可能成为内容管理和文档存储方面事实上的标准。
经过几乎2年半的努力,工作最终于2005年6月完成,在javax.jcr包中,API包含了大约50个类(主要是接口和异常)。2006年早些时候,发布了初始1.0版本的参考实现(JackRabbit)。
JSR-170概览Java内容仓库建立在仓库(除了是“用于安全地保存货物的地点”的通常含义之外)概念之上,它提供了几个操作数据的特性。仓库使用“树结构”保存信息,如下图,树由节点和属性组成。圆圈代表节点,方框代表属性。1个节点有且只有1个父亲,有任意数目的孩子(子节点)和任意数目的属性。1个属性有且只有一个父亲(它是节点),它没有子节点,由一个名字和一个或多个值组成。属性值的类型可以是:布尔(Boolean)、日期(Date)、双精(Double),长整(Long),字符串(String)或流(Stream)。只有属性可以被用来存储信息,节点则被用来创建树内部的“路径”。在某种程度上,这棵树类似文件系统的结构,节点是目录,属性是实际的文件。
仓库的功能被划分为几个“兼容性”级别,每个级别提供一组特定的特性:
相关厂商内容
一路走来技术人的创业故事 未来物联网中智能硬件的角色 人工智能的技术版图 Swift到底可以正式使用了吗? 不要写死!天猫App的动态化配置中心实践 相关赞助商

ArchSummit深圳2016将于7月15-16在华侨城洲际大酒店举行,现价8折抢购,团购报名更多优惠!
级别 1对于所有实现,级别1是必须的,它提供对仓库的读访问,简而言之:
对节点和属性的读访问。
对属性值的读访问。
输出到XML/SAX。
支持XPATH语法的查询服务。
级别 2级别2提供写功能:
增加和移除节点和属性。
对属性值的写操作。
从XML/SAX输入数据。
值得注意的是,JCR的实现并不要求达到级别2或者更高层次。因此与只读仓库一起工作也是完全符合规范的。
可选级别“可选”级别包含一些高级特性,它并不是读写仓库所必需的,但确是真正为JSR-170增色的部分。这个级别包括(除了其它之外):
事务 —— 它使仓库有可能与JMS或JDBC资源一起工作。
版本标定 —— 允许仓库记录节点的不同状态,以备日后检索。规范对于这个主题有相当的篇幅;该特性使得用JSR-170作为后端构建一个CVS的克隆成为可能。
事件 —— 亦称观察,它允许仓库内发生的任何活动都会被通知给客户端。
锁 —— 可以冻结部分树的功能,它可以有效地返回一个只读的子树。
API回顾使用JSR-170时,建议使用来自javax.jcr包的接口。这样,更换JCR实现时会容易些,不会有任何代码的变动。
API的核心类是Session,它代表客户端和仓库之间的连接,使用连接活跃其上的workspace名和所提供的credentials进行定义。Session包含读(级别1)和写(级别2)方法;使用底层仓库不支持的功能时将抛出异常。
这个包还包含了那些组成仓库的单元接口的定义:Workspace,Credentials,Node,Property,Item(Node和Property的超类)和Value。javax.jcr.query包负责处理查询,javax.jcr.nodetype包负责定义节点类型。剩余的包负责可选级别的功能,如javax.jcr.version、javax.jcr.observation、javax.jcr.lock。一个有趣的包是javax.jcr.util,它包含一个ItemVisitor的实现,它源自GOF(四人帮,Gang of Four)撰写的著名的设计模式中的访问者模式(Visitor-pattern)接口。
JSR-170实现Google和SourceForge会列出好几页的JSR-170实现,但是它们中的大多数都处于alpha阶段,没有发布任何版本。以下是一个可以自由下载的项目列表,它们已经被作者使用过:
Jackrabbit
它是JSR-170的参考实现,Apache基金的一部分,提供级别1,2和可选功能。在撰写本文时,它已经经过孵化阶段并有一个官方公开的发布版本,该版本被认为足够稳定,可以被用在产品环境。此外,Jackrabbit也被用来作为Day Software(JSR-170的领导者)的商业产品的基础。除了实现JSR-170中定义的所有特性,JackRabbit还加入了额外的功能(如SessionListeners或CustomNode注册),以及一个有趣的捐献来的项目套件,它包括:JCA连接器、taglib、WebDAV接口、虚拟文件系统和JDBC后端。JackRabbit的许可证是Apache 2.0。
eXo JCR
它是eXo platoform的一部分,包含规范要求的所有强制特性和几个可选特性。最近一次的版本发布(1.0RC7)是2006年6月22日,基于规范的最终草案2。eXo JCR支持JDBC兼容数据库,如MySQL、DB2或HSQL(它是缺省的)作为后端存储,它是双许可的(GPL和商用),最终版的发布日期尚未确定。
Jeceira
与Jackrabbit和eXo JCR相比,它是相对较新的项目。它实现了级别1和2的一些需求,只在写操作时,支持来自可选级别的观察功能。不幸的是,这个项目处于未完成阶段,在过去的9个月没有新版本发布。然而它被Magnolia(一个流行的基于java的CMS,与作为JSR-170参考实现的Jackrabbit类似)使用。在最终版发布时,它计划包含所有级别的功能,发布时间目前尚不确定。Jeceira的许可证是Apache 2.0,使用HSQL数据库作为它的存储引擎。
JCR模块Spring Modules的一部分,JCR模块的主要目标是:以一种类似Spring主分发包中ORM包的方式,简化使用JSR-170 API进行开发。特点如下:
JcrTemplate,允许执行JcrCallback和异常处理(将需检查的JCR异常转换成不需检查的Spring DAO异常)。这个模板实现了来自JCR Session的绝大部分方法,可以简单地作为替换物使用。此外该模板知道线程绑定的会话,这个会话可以跨几个方法使用,这在使用事务型仓库时非常有用。
RepositoryFactoryBean,它配置、启动和停止仓库实例。因为JSR-170并没有说明仓库配置的标准方式,需要注意实现在这个方面的不同。这个支持包含预定义的用于Jackrabbit和Jeceira的FactoryBean,以及一个可以很容易支持其它仓库的抽象基类。
SessionFactory,用来统一Repository,Credentials和Workspace接口,允许自动注册监听器和自定义名字空间。
Spring声明性事务为那些实现了(可选)事务特性的仓库提供了支持。
OpenSessionInView拦截器和过滤器允许每个线程跨不同组件使用同一会话。与JcrTemplate一起,检索、关闭和管理JCR会话的工作已经外部化,对于调用者完全透明。
本文将使用参考实现(Jackrabbit),由于JCR模块使用的是javax.jcr接口,因此改变实现根本就是一个配置的问题。让我们一步一步地来看看在Jackrabbit之上如何使用Java内容仓库,以及如何让Spring模块来帮助完成这一工作。
配置仓库和SessionFactory JCR支持提供RepositoryFactoryBean类配置Jackrabbit,它需要JackRabbit的配置文件和主目录。注意,RepositoryFactoryBean在使用本地文件系统时特别有用;对于服务器环境,仓库可能被注册在JNDI中,此时可以使用JndiObjectFactoryBean帮助类(Spring分发包的一部分)检索它:
或使用Spring 2.0的模式名字空间:
为了简化与JCR的工作,模块增加了SessionFactory接口:
public interface SessionFactory { public Session getSession() throws RepositoryException; public SessionHolder getSessionHolder(Session session);}SessionFactory隐藏了实现内部的认证细节,因此一旦配置完成,使用同一证书的会话可以很容易的被检索出来。为了利用实现的特性(没有涵盖在规范中的),这个接口允许检索SessionHolder。它是一个JCR模块特定类,主要被用于事务和会话管理(通过一种可用于每个JCR实现的缺省、通用实现),但是它不支持可选特性或自定义特性(如JackrabbitSessionHolder,它支持Jackrabbit的事务基础结构)。JCR模块提供一种简易、透明的方式来发现SessionHolder实现(这些我将在以后详细提到),使之很容易地插入对JSR-170其它兼容库的支持。
SessionFactory的缺省实现是JcrSessionFactory,它要求一个进行工作的仓库和证书。

 类似资料: