资源描述:
《hibernate二级缓存源代码解析》由会员上传分享,免费在线阅读,更多相关内容在教育资源-天天文库。
1、废话不说,今天花了一个下午的时间,专门啃Hibernate的二级缓存部分.Hibernate要支持好几种缓存,那么它肯定封装了各种不同的缓存策略,根据不同的缓存产品(如EHCache,JbossCache)相应处理.我手上的源码版本是Hibernate-3.3.1GA,按照org.hibernate.cache包里面的说明文件package.html的说明,这个版本相比以前,已经不再使用org.hibernate.cache.Cache/CacheProvider接口,转而使用了org.hibernate.cache.Region/Region
2、Factory接口,并且每个Region独立创建自己对缓存的访问策略.(Hibernate为每个实体类创建一个Region作为缓存区,默认情况下使用类的全路径名做为这个Region的名称)我个人认为,看代码应该要带着自己的问题去跟踪,这样才能做到线索清晰,目的明确.Hibernate的二级缓存有实体类的缓存和集合的缓存,下面以实体类的缓存为例,跟踪Hibernate的二级缓存处理过程.*问题1,既然Hibernate使用二级缓存,那么他的二级缓存是什么时候创建的?答案很简单,是在SessionFactoryImpl实例化的时候创建的.org.h
3、ibernate.cache.RegionFactory有个方法publicEntityRegionbuildEntityRegion(StringregionName,Propertiesproperties,CacheDataDescriptionmetadata)throwsCacheException;顾名思义,是用来创建缓存区的,跟踪一下什么方法调用的就行.从SessionFactoryImpl244行开始有一段:图1我最初的想法是认为Hibernate在我们使用到某个类的时候(比如通过session.load(class,id)方法
4、)才会创建缓存区并且加载缓存对象,这样可能更符合"懒"加载的特性.这里我不是很明白为什么Hibernate提前初始化了这些缓存区.不过,实际情况中,很多的应用都是在一开始就加载业务数据缓存,比如角色定义,规则,模板等等的对象.相对这些操作而言,Hibernate创建缓存区并不算大的开销.(我见过某些系统初始加载耗时半个钟)*问题二,Hibernate创建缓存区的时候,里面发生了什么事情?Hibernate的作者说"创建SessionFactory的代价非常昂贵,而创建Session的代价很低".此话至少前半句不假.看上面的代码,就知道实例化的时
5、候创建缓存区和对应的访问策略,如果实体类超过100个,就要创建100个缓存区和策略,相比创建一个Session,确实就有些耗费不起.我们跟踪到settings.getRegionFactory().buildEntityRegion(..)方法内部看看发生了什么.1)buildEntityRegion()方法org.hibernate.cache.RegionFactory是一个接口,它的实现类有两个.org.hibernate.cache包的NoCachingRegionFactory和RegionFactoryCacheProviderBr
6、idge.NoCachingRegionFactory是一个不提供缓存的实现,RegionFactoryCacheProviderBridge则是正常使用缓存的实现.看它的buildEntityRegion()方法:publicEntityRegionbuildEntityRegion( StringregionName, Propertiesproperties, CacheDataDescriptionmetadata)throwsCacheException{ returnnewEntityRegionAdapter(cac
7、heProvider.buildCache(regionName,properties),settings,metadata);}很简单,返回一个EntityRegionAdapter对象.这个对象需要三个参数:Cache,Settings,CacheDataDescription.Cache对象由cacheProvider.buildCache(regionName,properties)代劳,其他对象则是SessionFactory提供的.此处有两个奇怪的地方,为什么是EntityRegionAdapter?一般而言,adapter模式是为
8、协调两种不同结构的对象而设计的,其次,这里涉及到了Cache,CacheProvider接口,Hibernate在org.hibernate.cach