Class MultiLevelCache
- All Implemented Interfaces:
org.springframework.cache.Cache
Main goals are:
- Bypass calls to Redis to speed up retrieval entries
- Provide fault tolerance means if Redis is unavailable without loss in functionality
WARNING: When dealing with local cache we do partial key conversion using RedisCache.convertKey(Object) for consistency and retrieval of correct String
-
Nested Class Summary
Nested classes/interfaces inherited from interface org.springframework.cache.Cache
org.springframework.cache.Cache.ValueRetrievalException, org.springframework.cache.Cache.ValueWrapper -
Field Summary
FieldsModifier and TypeFieldDescriptionprotected final io.github.resilience4j.circuitbreaker.CircuitBreakerprotected final com.github.benmanes.caffeine.cache.Cache<Object,ReentrantLock> protected final MultiLevelCacheConfigurationProperties -
Constructor Summary
ConstructorsConstructorDescriptionMultiLevelCache(String name, MultiLevelCacheConfigurationProperties properties, org.springframework.data.redis.cache.RedisCacheWriter redisCacheWriter, org.springframework.data.redis.core.RedisTemplate<Object, Object> redisTemplate, com.github.benmanes.caffeine.cache.Cache<Object, Object> localCache, io.github.resilience4j.circuitbreaker.CircuitBreaker cacheCircuitBreaker) Creates a new instance of MultiLevelCache.MultiLevelCache(String name, MultiLevelCacheConfigurationProperties properties, org.springframework.data.redis.core.RedisTemplate<Object, Object> redisTemplate, com.github.benmanes.caffeine.cache.Cache<Object, Object> localCache, io.github.resilience4j.circuitbreaker.CircuitBreaker cacheCircuitBreaker) Initializes a new instance of the MultiLevelCache class with the given parameters. -
Method Summary
Modifier and TypeMethodDescriptionvoidclear()Clear the cache through removing all mappings.voidEvict the mapping for this key from this cache if it is present.booleanevictIfPresent(Object key) Evict the mapping for this key from this cache if it is present, expecting the key to be immediately invisible for later lookups.<T> TReturn the value to which this cache maps the specified key, obtaining that value fromvalueLoaderif necessary.booleanInvalidate the cache through removing all mappings, expecting all entries to be immediately invisible for later lookups.protected ObjectPerform an actual lookup in the underlying store.voidAssociate the specified value with the specified key in this cache.org.springframework.cache.Cache.ValueWrapperputIfAbsent(Object key, Object value) Atomically associate the specified value with the specified key in this cache if it is not set already.Methods inherited from class org.springframework.data.redis.cache.RedisCache
clear, clearStatistics, convertKey, createCacheKey, deserializeCacheValue, getCacheConfiguration, getCacheWriter, getConversionService, getName, getNativeCache, getStatistics, loadCacheValue, preProcessCacheValue, retrieve, retrieve, serializeCacheKey, serializeCacheValueMethods inherited from class org.springframework.cache.support.AbstractValueAdaptingCache
fromStoreValue, get, get, isAllowNullValues, toStoreValue, toValueWrapper
-
Field Details
-
properties
-
localCache
-
locks
-
cacheCircuitBreaker
protected final io.github.resilience4j.circuitbreaker.CircuitBreaker cacheCircuitBreaker
-
-
Constructor Details
-
MultiLevelCache
public MultiLevelCache(String name, MultiLevelCacheConfigurationProperties properties, org.springframework.data.redis.core.RedisTemplate<Object, Object> redisTemplate, com.github.benmanes.caffeine.cache.Cache<Object, Object> localCache, io.github.resilience4j.circuitbreaker.CircuitBreaker cacheCircuitBreaker) Initializes a new instance of the MultiLevelCache class with the given parameters.- Parameters:
name- The name of the cache.properties- The configuration properties for the cache.redisTemplate- The Redis template used for accessing the Redis cache.localCache- The local cache used as an additional level of caching.cacheCircuitBreaker- The circuit breaker used for handling cache failures.
-
MultiLevelCache
public MultiLevelCache(String name, MultiLevelCacheConfigurationProperties properties, org.springframework.data.redis.cache.RedisCacheWriter redisCacheWriter, org.springframework.data.redis.core.RedisTemplate<Object, Object> redisTemplate, com.github.benmanes.caffeine.cache.Cache<Object, Object> localCache, io.github.resilience4j.circuitbreaker.CircuitBreaker cacheCircuitBreaker) Creates a new instance of MultiLevelCache.- Parameters:
name- The name of the cache.properties- The configuration properties for the cache.redisCacheWriter- The Redis cache writer to use.redisTemplate- The Redis template used for accessing the Redis cache.localCache- The local cache used as an additional level of caching.cacheCircuitBreaker- The circuit breaker used for handling cache failures.
-
-
Method Details
-
lookup
Perform an actual lookup in the underlying store.We do not allow storing
nullvalues, if local cache does not have a mapping for specified key we query Redis using circuit breaker and error handling logic. If Redis contains requested mapping, the value will be saved in the local cache. If Redis is not available,nullwill be returned.- Overrides:
lookupin classorg.springframework.data.redis.cache.RedisCache- Parameters:
key- the key whose associated value is to be returned- Returns:
- the raw store value for the key, or
nullif none
-
get
Return the value to which this cache maps the specified key, obtaining that value fromvalueLoaderif necessary. This method provides a simple substitute for the conventional "if cached, return; otherwise create, cache and return" pattern.If the
valueLoaderthrows an exception, it is wrapped in aCache.ValueRetrievalExceptionIf Redis cannot be queried,
valueLoaderwill still be executed and value will be stored in local cache instead.- Specified by:
getin interfaceorg.springframework.cache.Cache- Overrides:
getin classorg.springframework.data.redis.cache.RedisCache- Parameters:
key- the key whose associated value is to be returned- Returns:
- the value to which this cache maps the specified key
- Throws:
org.springframework.cache.Cache.ValueRetrievalException- if thevalueLoaderthrows an exception or retrieved value wasnull- See Also:
-
AbstractValueAdaptingCache.get(Object)
-
put
Associate the specified value with the specified key in this cache.If the cache previously contained a mapping for this key, the old value replaced by the specified value.
If value is
nullspecified key will be evicted.Actual registration performed in an asynchronous fashion, with later lookups possibly not seeing the entry yet.
Use
putIfAbsent(java.lang.Object, java.lang.Object)for guaranteed immediate registration for current cache.- Specified by:
putin interfaceorg.springframework.cache.Cache- Overrides:
putin classorg.springframework.data.redis.cache.RedisCache- Parameters:
key- the key with which the specified value is to be associatedvalue- the value to be associated with the specified key- See Also:
-
putIfAbsent
public org.springframework.cache.Cache.ValueWrapper putIfAbsent(@NonNull Object key, @Nullable Object value) Atomically associate the specified value with the specified key in this cache if it is not set already.This is equivalent to:
except that the action performed atomically for current cache.ValueWrapper existingValue = cache.get(key); if (existingValue == null) { cache.put(key, value); } return existingValue;If value is
nullspecified key will be evicted.- Specified by:
putIfAbsentin interfaceorg.springframework.cache.Cache- Overrides:
putIfAbsentin classorg.springframework.data.redis.cache.RedisCache- Parameters:
key- the key with which the specified value is to be associatedvalue- the value to be associated with the specified key- Returns:
- the value to which this cache maps the specified key (which may be
nullitself), or alsonullif the cache did not contain any mapping for that key prior to this call. Returningnullis therefore an indicator that the givenvaluehas been associated with the key, or it was evicted. - See Also:
-
evict
Evict the mapping for this key from this cache if it is present.Actual eviction performed in an asynchronous fashion, with later lookups possibly still seeing the entry. Use
evictIfPresent(java.lang.Object)for guaranteed immediate removal for current cache.- Specified by:
evictin interfaceorg.springframework.cache.Cache- Overrides:
evictin classorg.springframework.data.redis.cache.RedisCache- Parameters:
key- the key whose mapping is to be removed from the cache- See Also:
-
evictIfPresent
Evict the mapping for this key from this cache if it is present, expecting the key to be immediately invisible for later lookups.- Parameters:
key- the key whose mapping is to be removed from the cache- Returns:
trueif local cache was known to have a mapping for this key before,falseif it did not (or if prior presence could not be determined)- Since:
- 5.2
- See Also:
-
clear
public void clear()Clear the cache through removing all mappings.Actual clearing performed in an asynchronous fashion, with later lookups possibly still seeing the entries. Use
invalidate()for guaranteed immediate removal of entries for current cache.- Specified by:
clearin interfaceorg.springframework.cache.Cache- Overrides:
clearin classorg.springframework.data.redis.cache.RedisCache- See Also:
-
invalidate
public boolean invalidate()Invalidate the cache through removing all mappings, expecting all entries to be immediately invisible for later lookups.- Returns:
trueif local cache was known to have mappings before,falseif it did not (or if prior presence of entries could not be determined)- Since:
- 5.2
- See Also:
-