本文主要研究一下jetcache的ProxyCache
jetcache-core/src/main/java/com/alicp/jetcache/ProxyCache.java
ProxyCache继承了Cache接口,它定义了getTargetCache方法,并默认实现了unwrap方法
jetcache-core/src/main/java/com/alicp/jetcache/SimpleProxyCache.java
SimpleProxyCache实现了ProxyCache接口,它定义了cache属性,其方法均委托给了cache对象
jetcache-core/src/main/java/com/alicp/jetcache/LoadingCache.java
LoadingCache继承了SimpleProxyCache,其get方法会判断config.getLoader()是否为null,不为null则执行AbstractCache.computeIfAbsentImpl(key, loader,config.isCacheNullValue() ,0, null, this);getAll方法多了loader以及config.isCachePenetrationProtect()的处理逻辑,对于开启cachePenetrationProtect的会通过CacheUtil.createProxyLoader包装一下loader,然后AbstractCache.synchronizedLoad去加载value
jetcache-core/src/main/java/com/alicp/jetcache/CacheUtil.java
CacheUtil提供了两个createProxyLoader,一个loader类型为CacheLoader,一个为Function;其load及loadAll方法委托给了loader,主要是增加了耗时统计并创建CacheLoadEvent,交给eventConsumer.accept(event)去消费
jetcache-core/src/main/java/com/alicp/jetcache/AbstractCache.java
AbstractCache提供了synchronizedLoad静态方法,它先通过buildLoaderLockKey来创建lockKey,之后while循环,computeIfAbsent指定lockKey的LoaderLock,对于loaderThread为当前线程的先通过GET获取result,若为success则返回,否则通过loader加载,然后通知cacheUpdater,最后执行ll.signal.countDown(),对于非当前thread的则根据指定的timeout执行ll.signal.await(),若await超时或者InterruptedException则执行newLoader.apply,否则对于success的直接返回value,非success则继续循环处理
jetcache-core/src/main/java/com/alicp/jetcache/RefreshCache.java
RefreshCache继承了LoadingCache,它定义了taskMap用于存储RefreshTask,它覆盖了computeIfAbsent方法,复用了AbstractCache定义的静态方法computeIfAbsentImpl,传入的cache为this;其get及getAll方法对于config.getRefreshPolicy()及config.getLoader()不为null的会额外执行addOrUpdateRefreshTask
addOrUpdateRefreshTask方法先获取refreshMillis,对于refreshMillis小于等于0的不处理,大于0的先通过getTaskId(key)获取taskId,然后通过taskMap.computeIfAbsent获取或者创建refreshTask,最后更新refreshTask的lastAccessTime;当新创建refreshTask时,会通过JJetCacheExecutor.heavyIOExecutor().scheduleWithFixedDelay(task, refreshMillis, refreshMillis, TimeUnit.MILLISECONDS)去调度该refreshTask,即每隔refreshMillis调度执行refreshTask
RefreshTask的run方法先判断stopRefreshAfterLastAccessMillis,若stopRefreshAfterLastAccessMillis大于0且lastAccessTime + stopRefreshAfterLastAccessMillis小于now则执行cancel,然后返回;之后通过concreteCache获取具体的cache,对于AbstractExternalCache类型的执行externalLoad,否则执行load load方法通过loader去加载,对于needUpdate的执行PUT去更新;对于externalLoad的会先获取refreshTimeResult,对于CacheResultCode.NOT_EXISTS的则shouldLoad为true,对于refreshTimeResult.isSuccess()的对于currentTime大于等于Long.parseLong(refreshTimeResult.getValue().toString()) + refreshMillis的则shouldLoad为true,对于非shouldLoad的且是multiLevelCache则执行refreshUpperCaches然后返回;否则使用concreteCache.tryLockAndRun去加锁然后执行load方法,若加锁不成功且是multiLevelCache的,则通过JetCacheExecutor.heavyIOExecutor().schedule去调度执行refreshUpperCaches
jetcache-core/src/main/java/com/alicp/jetcache/SimpleCacheManager.java
SimpleCacheManager的create方法对于config.getRefreshPolicy()不为null的则创建RefreshCache去包装cache,否则再对于config.getLoader()不为null使用LoadingCache去包装cache
ProxyCache继承了Cache接口,它定义了getTargetCache方法,并默认实现了unwrap方法;SimpleProxyCache实现了ProxyCache接口,它定义了cache属性,其方法均委托给了cache对象
LoadingCache继承了SimpleProxyCache,其get方法会判断config.getLoader()是否为null,不为null则执行AbstractCache.computeIfAbsentImpl(key, loader,config.isCacheNullValue() ,0, null, this);getAll方法多了loader以及config.isCachePenetrationProtect()的处理逻辑,对于开启cachePenetrationProtect的会通过CacheUtil.createProxyLoader包装一下loader,然后AbstractCache.synchronizedLoad去加载value RefreshCache继承了LoadingCache,它定义了taskMap用于存储RefreshTask,它覆盖了computeIfAbsent方法,复用了AbstractCache定义的静态方法computeIfAbsentImpl,传入的cache为this;其get及getAll方法对于config.getRefreshPolicy()及config.getLoader()不为null的会额外执行addOrUpdateRefreshTask SimpleCacheManager的create方法根据QuickConfig先构造local或者remote或者multiLevelCache,再根据config的loader或者refreshPolicy去创建包装类,对于config.getRefreshPolicy()不为null的则创建RefreshCache去包装cache,否则再对于config.getLoader()不为null使用LoadingCache去包装cache