hibernate二级缓存(二)二级缓存实现原理简单剖析
hibernate二級緩存(二)二級緩存實現原理簡單剖析
在前面我們將過hibernate二級緩存類似于一個插件,將緩存的具體實現分離,緩存的具體實現是通過hibernate.cache.region.factory_class參數配置指定。本文只是對hibernate二級緩存的部分接口進行簡單的解析,大致了解二級緩存的整體結構,二級緩存的內部實現很復雜,如要深究請閱讀hibernate源碼。
1. hibernate二級緩存結構
hibernate二級緩存涉及到如下幾個重要的接口:
- RegionFactory
- DomainDataRegion
- EntityDataAccess
- StorageAccess
1.1 RegionFactory獲取緩存的工廠,RegionFactory有如下幾個重要的方法:
public interface RegionFactory extends Service, Stoppable {//初始化方法void start(SessionFactoryOptions settings, Map configValues) throws CacheException;boolean isMinimalPutsEnabledByDefault();//緩存策略AccessType getDefaultAccessType();String qualify(String regionName);default CacheTransactionSynchronization createTransactionContext(SharedSessionContractImplementor session) {return new StandardCacheTransactionSynchronization( this );}long nextTimestamp();default long getTimeout() {// most existing providers defined this as 60 seconds.return 60000;}DomainDataRegion buildDomainDataRegion(DomainDataRegionConfig regionConfig,DomainDataRegionBuildingContext buildingContext);QueryResultsRegion buildQueryResultsRegion(String regionName, SessionFactoryImplementor sessionFactory);TimestampsRegion buildTimestampsRegion(String regionName, SessionFactoryImplementor sessionFactory); }- start 初始化RegionFactory
- getDefaultAccessType 獲得緩存策略,前面說過的CacheConcurrencyStrategy內部是基于AccessType
- nextTimestamp 生成時間戳,用于時間戳緩存
- buildDomainDataRegion 創建一個實體領域模型的Region,使用該對象來緩存實體,可以理解為實體緩存的holder
- buildQueryResultsRegion 創建查詢緩存
- buildTimestampsRegion 創建時間戳緩存。時間戳緩存Region存放了對于查詢結果相關的表進行插入, 更新或刪除操作的時間戳。Hibernate 通過時間戳緩存Region來判斷被緩存的查詢結果是否過期
RegionFactory 是創建緩存的工廠,所有的緩存都是通過RegionFactory 來獲取的,而RegionFactory 是在EnabledCaching構造方法中初始化的。RegionFactory 的初始化過程如下圖所示:
sessionFactory = new MetadataSources(registry).buildMetadata().buildSessionFactory();可以看到是在初始化sessionFactory的時候來初始化RegionFactory 。
1.2 DomainDataRegion緩存區域
DomainDataRegion可以理解為緩存的wraper或者holder。接口如下:
public interface DomainDataRegion extends Region {EntityDataAccess getEntityDataAccess(NavigableRole var1);NaturalIdDataAccess getNaturalIdDataAccess(NavigableRole var1);CollectionDataAccess getCollectionDataAccess(NavigableRole var1); }getEntityDataAccess 獲得一個EntityDataAccess,對緩存的操作實際上是代理給EntityDataAccess,由EntityDataAccess來真正的管理緩存。
1.3 EntityDataAccess 緩存實際的訪問者,用于管理對緩存實體數據的事務性和并發訪問的協定
public interface EntityDataAccess extends CachedDomainDataAccess {//生成緩存keyObject generateCacheKey(Object id,EntityPersister rootEntityDescriptor,SessionFactoryImplementor factory,String tenantIdentifier);//獲取緩存keyObject getCacheKeyId(Object cacheKey);//在查詢后,是否將查詢結果插入緩存boolean insert(SharedSessionContractImplementor session, Object key, Object value, Object version);//插入后是否更新緩存boolean afterInsert(SharedSessionContractImplementor session, Object key, Object value, Object version);boolean update(SharedSessionContractImplementor session,Object key,Object value,Object currentVersion,Object previousVersion);boolean afterUpdate(SharedSessionContractImplementor session,Object key,Object value,Object currentVersion,Object previousVersion,SoftLock lock); }在上面的接口中我們并沒有看到實際操作緩存的接口,那么EntityDataAccess 又是怎么訪問和管理緩存的呢,下面來看一下EntityDataAccess 的接口繼承和實現關系:
從上面的圖我們可以看到EntityDataAccess 有一個抽象類,4個實現類。4個實現類分別對應了4中緩存訪問類型,READ_ONLY,TRANSACTIONAL,READ_WRITE,NONSTRICT_READ_WRITE。抽象類AbstractEntityDataAccess實現了
EntityDataAccess 繼承了AbstractCachedDomainDataAccess。AbstractCachedDomainDataAccess的部分代碼如下:
AbstractCachedDomainDataAccess里面包含了一個DomainDataStorageAccess,DomainDataStorageAccess繼承自StorageAccess,StorageAccess的接口如下:
到這里我們終于發現了操作緩存的實際接口。而DomainDataStorageAccess接口是緩存操作必須實現的接口,ehchche的實現類是StorageAccessImpl。當然通過擴展該接口我們還可以將緩存放置到redis,memcache。
2. 緩存的初始化和調用
2.1 從上面的接口關系我們大致可以得到如下的一個緩存初始化關系鏈:
sessionFactory ----->EnabledCaching ----->RegionFactory ----->DomainDataRegion ----->EntityDataAccess ----->AbstractEntityDataAccess ----->AbstractCachedDomainDataAccess ----->StorageAccess
2.2 獲取cache的調用棧
SessionImpl獲取實體對象,然后通過一系列的調用,最終會落到AbstractCachedDomainDataAccess.get(SharedSessionContractImplementor session, Object key),前面已經說過該方法實際上是調用的DomainDataStorageAccess.getFromCache( key, session )。
3. 自定義hibernate緩存
通過前面的一系列分析,我們大致了解了hibernate緩存的一些重要的接口。如果要自定義hibernate緩存那么我們必須實現上面的這些接口。好在hibernate內部為實現了大多數的擴展,我們只需要擴展RegionFactory和DomainDataStorageAccess接口既可以自定義hibernate的二級緩存。
hibernate為實現RegionFactory提供了一個模版類RegionFactoryTemplate,我們直接通過實現該類和DomainDataStorageAccess,即可自定義hibernate二級緩存。
總結
以上是生活随笔為你收集整理的hibernate二级缓存(二)二级缓存实现原理简单剖析的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: My sql 存储过程实例
- 下一篇: Mac上删除音频设备