




全文预览已结束
下载本文档
版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
废话不说,今天花了一个下午的时间, 专门啃Hibernate的二级缓存部分. Hibernate要支持好几种缓存, 那么它肯定封装了各种不同的缓存策略, 根据不同的缓存产品(如EHCache,Jboss Cache)相应处理.我手上的源码版本是Hibernate-3.3.1GA, 按照org.hibernate.cache包里面的说明文件package.html的说明, 这个版本相比以前, 已经不再使用org.hibernate.cache.Cache/CacheProvider接口, 转而使用了org.hibernate.cache.Region/RegionFactory接口, 并且每个Region独立创建自己对缓存的访问策略. (Hibernate为每个实体类创建一个Region作为缓存区, 默认情况下使用类的全路径名做为这个Region的名称)我个人认为, 看代码应该要带着自己的问题去跟踪, 这样才能做到线索清晰, 目的明确. Hibernate的二级缓存有实体类的缓存和集合的缓存, 下面以实体类的缓存为例, 跟踪Hibernate的二级缓存处理过程.* 问题1, 既然Hibernate使用二级缓存, 那么他的二级缓存是什么时候创建的?答案很简单, 是在SessionFactoryImpl实例化的时候创建的. org.hibernate.cache.RegionFactory有个方法 public EntityRegion buildEntityRegion(String regionName, Properties properties, CacheDataDescription metadata) throws CacheException; 顾名思义, 是用来创建缓存区的, 跟踪一下什么方法调用的就行.从SessionFactoryImpl 244行开始有一段:图1我最初的想法是认为Hibernate在我们使用到某个类的时候(比如通过session.load(class,id)方法)才会创建缓存区并且 加载缓存对象, 这样可能更符合懒加载的特性. 这里我不是很明白为什么Hibernate提前初始化了这些缓存区. 不过, 实际情况中, 很多的应用都是在一开始就加载业务数据缓存, 比如角色定义, 规则, 模板等等的对象. 相对这些操作而言, Hibernate创建缓存区并不算大的开销.(我见过某些系统初始加载耗时半个钟)* 问题二, Hibernate创建缓存区的时候, 里面发生了什么事情?Hibernate的作者说创建SessionFactory的代价非常昂贵, 而创建Session的代价很低. 此话至少前半句不假. 看上面的代码, 就知道实例化的时候创建缓存区和对应的访问策略, 如果实体类超过100个, 就要创建100个缓存区和策略, 相比创建一个Session, 确实就有些耗费不起. 我们跟踪到settings.getRegionFactory().buildEntityRegion(.)方法内部看看发生了什么.1) buildEntityRegion() 方法org.hibernate.cache.RegionFactory是一个接口, 它的实现类有两个. org.hibernate.cache包的 NoCachingRegionFactory和RegionFactoryCacheProviderBridge. NoCachingRegionFactory是一个不提供缓存的实现, RegionFactoryCacheProviderBridge则是正常使用缓存的实现. 看它的buildEntityRegion()方法:public EntityRegion buildEntityRegion( String regionName, Properties properties, CacheDataDescription metadata) throws CacheException return new EntityRegionAdapter( cacheProvider.buildCache( regionName, properties ), settings, metadata );很简单, 返回一个EntityRegionAdapter对象. 这个对象需要三个参数:Cache, Settings, CacheDataDescription. Cache对象由cacheProvider.buildCache( regionName, properties )代劳, 其他对象则是SessionFactory提供的.此处有两个奇怪的地方, 为什么是EntityRegionAdapter? 一般而言, adapter模式是为协调两种不同结构的对象而设计的, 其次, 这里涉及到了Cache, CacheProvider接口, Hibernate在org.hibernate.cache包的说明里面已经声明Cache, CacheProvider接口作废. 显然, 结论只能是, Hibernate用来一套新的API替代了原来的API, 但是接口下面的实现, 仍旧依赖原来的实现!于是, 花点时间, 先把org.hibernate.cache包地下的类的结构搞清楚. 我的方法比较笨, 就是一个一个类去看,然后用UML画出来. 如果用一些工具的逆向工程, 我感觉就是喝了白开水, 看过就完事, 一点印象都没有. 不过类层次关系比较复杂, 我只好以缩略图的方式贴上来.图2很明显, Hibernate的cache源码分类五块:第一块是访问策略, 在org.hibernate.cache.access包内. 几个类的名字很清晰的表明了意思: AccessType - 访问类型, read-only, read-write等. EntityRegionAccessStrategy - 实体类访问策略. 其实就是class的缓存访问策略. CollectionRegionAccessStrategy - 集合的访问策略. 其实就是class内的集合的缓存访问策略. 对象的获得都是通过这两种方式来代理给Cache对象处理的.第二块: 代理层, 在org.hibernate.cache.impl.bridge包内. 可以见到中间有一块, 全是xxxAdapter, 分别用于代理实体, 集合, 查询结果的缓存, 透过org.hibernate.cache.CacheConcurrencyStrategy给Cache对象处理请求.第三块: 原来的缓存实现部分. 在org.hibernate.cache包内.主要由org.hibernate.cache.CacheConcurrencyStrategy/ Cache/ CacheProvider三个接口组成.第四块: 新的缓存API, 在org.hibernate.cache包内.包括几个主要的接口: org.hibernate.cache.Region/ TransactionalDataRegion/ EntityRegion/ CollectionRegion/ QueryResultRegion/ RegionFactory/ CacheKey. 在CollectionRegion和EntityRegion两个类上分别创建了CollectionRegionAccessStrategy和 EntityRegionAccessStrategy.第无块: 缓存对象入口. 在org.hibernate.cache.entry包内. 这些对象是SessionFactory和二级缓存打交道的封装. 在每个对象被放入缓存的时刻, 会被封装到一个Entry内, 透过Region来传递给真正的Cache Provider(如EHCache). 但是, 这里我们并没有看到具体的Entry从Region传递到EHCache的代码, 这个版本里已经把原来的org.hibernate.cache.EHCacheProvider分离出去了,作为一个单独的hibernate- ehcache.jar包.有了这个图, 缓存的结构已经很清晰了. 上面代码中的cacheProvider.buildCache( regionName, properties ), 其实就是按照Hibernate.cfg.xml中提供的CacheProvider创建的Cache. 看一下我们很熟悉的配置org.hibernate.cache.EhCacheProvidertruefalse对应的EHCacheProvider代码:import net.sf.ehcache.CacheManager;.public class EhCacheProvider implements CacheProvider private CacheManager manager;. public Cache buildCache(String name, Properties properties) throws CacheException try net.sf.ehcache.Cache cache = manager.getCache(name); if (cache = null) log.warn(Could not find configuration + name + ; using defaults.); manager.addCache(name); cache = manager.getCache(name); log.debug(started EHCache region: + name); return new EhCache(cache); catch (net.sf.ehcache.CacheException e) throw new CacheException(e); .基本上, Cache接口提供的方法就是get(), put(), remove()之类的, 和java.util.Map接口类似, 另外还提供lock(), unlock()方法. 到这里, Hibernate对于实体类的缓存操作都交给EHCache去打理了.创建好实体类缓存区后, 谁来和它打交道呢? 答案就是EntityRegionAccessStrategy. 类层次结构见上图2. 从图1中就能发现, SessionFactoryImpl在创建好缓存区后, 就开始使用EntityRegion.buildAccessStrategy()方法创建EntityRegionAccessStrategy.2) buildAccessStrategy() 方法我们已经知道对应EntityRegion接口的实现类是EntityRegionAdapter, 看看它的代码, 很简单public class EntityRegionAdapter extends BaseTransactionalDataRegionAdapter implements EntityRegion private static final Logger log = LoggerFactory.getLogger( EntityRegionAdapter.class );public EntityRegionAdapter(Cache underlyingCache, Settings settings, CacheDataDescription metadata) super( underlyingCache, settings, metadata ); if ( underlyingCache instanceof OptimisticCache ) ( ( OptimisticCache ) underlyingCache ).setSource( new OptimisticCacheSourceAdapter( metadata ) ); public EntityRegionAccessStrategy buildAccessStrategy(AccessType accessType) throws CacheException CacheConcurrencyStrategy ccs; if ( AccessType.READ_ONLY.equals( accessType ) ) if ( metadata.isMutable() ) log.warn( read-only cache configured for mutable entity + getName() + ); ccs = new ReadOnlyCache(); else if ( AccessType.READ_WRITE.equals( accessType ) ) ccs = new ReadWriteCache(); else if ( AccessType.NONSTRICT_READ_WRITE.equals( accessType ) ) ccs = new NonstrictReadWriteCache(); else if ( AccessType.TRANSACTIONAL.equals( accessTyp
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 学习动力与创新思维教育心理学的奥秘
- 以技术驱动创新如何将虚拟现实技术融入商业教育中
- 前锋线比较法分析进度偏差
- 广西柳州铁一中、南宁三中 2025年物理高二第二学期期末预测试题含解析
- 中职教案课件
- 智慧城市公共交通的大数据治理与优化实践
- 医疗领域的教育心理学应用与实践
- 技术进步如何重塑商业模式与战略
- 教育心理学的创新应用对幼教的启示和影响
- 中职手工课课件
- 全国职业院校技能大赛赛项规程(高职)(高职)化工生产技术
- 零工市场(驿站)运营管理 投标方案(技术方案)
- 2024-2030年全球及中国光学器件中的透镜行业市场现状供需分析及市场深度研究发展前景及规划可行性分析研究报告
- KBR气化炉-合成氨
- DL∕T 741-2019 架空输电线路运行规程
- 临时用电安全责任确认书
- 网络运维专项方案
- 赫力昂:2024中国年轻群体痤疮外用药治疗白皮书
- 国家开放大学《合同法》章节测试参考答案
- 巡察知识讲解课件
- 多囊卵巢综合征诊治路径专家共识
评论
0/150
提交评论