Hibernate的缓存
Hibernate的缓存主要实现在net.sf.hibernate.cache包里。具体代码请查看Hibernate 源码。
1、Cache
此接口定义了缓存的一些基本操作,例如get,put,lock,unlock等。在此接口的基础上,Hibernate使用JCS等多种机制实现了缓存,包括:JCSCache,OSCache,SwarmCache,TreeCache,HashtableCache。由于整个缓存系统基本就是策略模式,所以,后面将只以JCSCache作为例子,其他的可以举一反三。
2、CacheProvider
此接口提供了配置Cache的方法:buildCache,还提供了取时间戳的方法:nextTimestamp。这里也用到了策略模式,拿buildCache来说,JCSCacheProvider和OSCacheProvider的实现方法就不一样,JCSCacheProvider只是简单的生成一个JCSCache的实例,而OSCacheProvider还进行了一些其他的处理。再来看看nextTimestamp,JCSCacheProvider直接调用时间戳类(Timestamper)来生成时间戳,这样使时间戳而SwarmCacheProvider却没有,它直接返回了一个值,精确度没有JCSCacheProvider高,但是速度却很快。
3、Timestamper
此类提供了生成时间戳的方法,它的next方法返回一个递增的时间戳,方法的实现使用了以为的办法,可以保证产生的时间戳在1/4000 ms内无重复。
4、CacheConcurrencyStrategy
此接口定义了对Cache进行操作的策略(其实这个不算是个策略模式,应该算代理模式),例如,ReadWriteCache,ReadOnlyCache等。对于这个是代理模式还是策略模式,从工厂类CacheFactory就可以看出来——createCache方法,它的返回值不是Cache类型,而是CacheConcurrencyStrategy类型。但是这里的代理模式又与标准的GoF的又有一点区别:如果按标准的代理模式,CacheConcurrencyStrategy应该继承Cache才对,但是这里对这两个接口是单独处理的。
5、二级锁
CacheConcurrencyStrategy接口里定义了一个空接口:SoftLock。这个接口没有任何的方法,它的功能是为实现二级锁留下空间。像JCS这样的缓存系统都提供了lock和unlock,可以实现对象的加锁与解锁操作。但是,有时候只是实现简单的lock操作是不够的,还需要加上某些条件,比如加上时间戳的判别等。
首先,我们来看看不要二级锁的情况,拿NonstrictReadWriteCache类来说,它实现了CacheConcurrencyStrategy接口,它的策略是不使用锁。所以,它里面的lock方法其实什么也没有做,仅仅只有"return null;"。
其次,我们再来看看ReadWriteCache类。这个类实现的策略是既使用Cache提供的锁,也使用自己的二级锁,以便对时间戳进行判定。因此,为了实现这个策略,类中还定义了以下几个接口和类:
public static interface Lockable {...}
public static final class Item implements Serializable, Lockable {...}
public static final class Lock implements Serializable, Lockable, SoftLock {...}
这几个类和接口是实现二级锁的核心:
Lockable接口也是一个策略——表示对于被加锁的对象,应该以什么方式来进行读写;
Item类实现了Lockable,它把缓存中存储的对象和该对象的时间戳封装在一起,同时实现了对象的只读锁。具体可以看它实现的Lockable接口的那三个方法
![ExpandedBlockStart.gif](/Images/OutliningIndicators/ExpandedBlockStart.gif)
![ContractedBlock.gif](/Images/OutliningIndicators/ContractedBlock.gif)
![dot.gif](/Images/dot.gif)
![InBlock.gif](/Images/OutliningIndicators/InBlock.gif)
![InBlock.gif](/Images/OutliningIndicators/InBlock.gif)
![InBlock.gif](/Images/OutliningIndicators/InBlock.gif)
![ExpandedBlockEnd.gif](/Images/OutliningIndicators/ExpandedBlockEnd.gif)
![ExpandedBlockStart.gif](/Images/OutliningIndicators/ExpandedBlockStart.gif)
![ContractedBlock.gif](/Images/OutliningIndicators/ContractedBlock.gif)
![InBlock.gif](/Images/OutliningIndicators/InBlock.gif)
![InBlock.gif](/Images/OutliningIndicators/InBlock.gif)
![ExpandedBlockEnd.gif](/Images/OutliningIndicators/ExpandedBlockEnd.gif)
![ExpandedBlockStart.gif](/Images/OutliningIndicators/ExpandedBlockStart.gif)
![ContractedBlock.gif](/Images/OutliningIndicators/ContractedBlock.gif)
![dot.gif](/Images/dot.gif)
![InBlock.gif](/Images/OutliningIndicators/InBlock.gif)
![InBlock.gif](/Images/OutliningIndicators/InBlock.gif)
![ExpandedBlockEnd.gif](/Images/OutliningIndicators/ExpandedBlockEnd.gif)
![None.gif](/Images/OutliningIndicators/None.gif)
![ExpandedBlockStart.gif](/Images/OutliningIndicators/ExpandedBlockStart.gif)
![ContractedBlock.gif](/Images/OutliningIndicators/ContractedBlock.gif)
![InBlock.gif](/Images/OutliningIndicators/InBlock.gif)
![ExpandedBlockEnd.gif](/Images/OutliningIndicators/ExpandedBlockEnd.gif)
![ExpandedBlockStart.gif](/Images/OutliningIndicators/ExpandedBlockStart.gif)
![ContractedBlock.gif](/Images/OutliningIndicators/ContractedBlock.gif)
![dot.gif](/Images/dot.gif)
![InBlock.gif](/Images/OutliningIndicators/InBlock.gif)
![InBlock.gif](/Images/OutliningIndicators/InBlock.gif)
![InBlock.gif](/Images/OutliningIndicators/InBlock.gif)
![InBlock.gif](/Images/OutliningIndicators/InBlock.gif)
![InBlock.gif](/Images/OutliningIndicators/InBlock.gif)
![ExpandedBlockEnd.gif](/Images/OutliningIndicators/ExpandedBlockEnd.gif)
![None.gif](/Images/OutliningIndicators/None.gif)
在这里我们看到,Item对象是只允许读,而不允许写的。
Lock对象只是一个锁对象而不是一个数据对象,它的作用只是作为一个锁,对于客户端来说没有什么特别的意义。
6、UpdateTimestampsCache
此类用于对缓存时间戳的更新进行追踪。由于此类还未完成,所以暂时不管。