diff --git a/src/main/java/org/springframework/data/redis/cache/RedisCache.java b/src/main/java/org/springframework/data/redis/cache/RedisCache.java index 9b82d35de..383fa69a2 100644 --- a/src/main/java/org/springframework/data/redis/cache/RedisCache.java +++ b/src/main/java/org/springframework/data/redis/cache/RedisCache.java @@ -43,7 +43,7 @@ class RedisCache implements Cache { private final byte[] setName; private final byte[] cacheLockName; private long WAIT_FOR_LOCK = 300; - private final long expire; + private final long expiration; /** * @@ -52,22 +52,22 @@ class RedisCache implements Cache { * @param name cache name * @param prefix * @param template - * @param expire - */ - RedisCache(String name, byte[] prefix, RedisTemplate template, long expire) { + * @param expiration + */ + RedisCache(String name, byte[] prefix, RedisTemplate template, long expiration) { Assert.hasText(name, "non-empty cache name is required"); this.name = name; this.template = template; this.prefix = prefix; - this.expire = expire; + this.expiration = expiration; StringRedisSerializer stringSerializer = new StringRedisSerializer(); // name of the set holding the keys this.setName = stringSerializer.serialize(name + "~keys"); - this.cacheLockName = stringSerializer.serialize(name + "~lock"); - } + this.cacheLockName = stringSerializer.serialize(name + "~lock"); + } public String getName() { return name; @@ -83,10 +83,10 @@ class RedisCache implements Cache { return template; } - + public ValueWrapper get(final Object key) { return (ValueWrapper) template.execute(new RedisCallback() { - + public ValueWrapper doInRedis(RedisConnection connection) throws DataAccessException { waitForLock(connection); byte[] bs = connection.get(computeKey(key)); @@ -95,7 +95,7 @@ class RedisCache implements Cache { }, true); } - + public void put(final Object key, final Object value) { final byte[] k = computeKey(key); @@ -104,10 +104,13 @@ class RedisCache implements Cache { waitForLock(connection); connection.multi(); connection.set(k, template.getValueSerializer().serialize(value)); - if (expire > 0) { - connection.expire(k, expire); - } connection.zAdd(setName, 0, k); + + if (expiration > 0) { + connection.expire(k, expiration); + // update the expiration of the set of keys as well + connection.expire(setName, expiration); + } connection.exec(); return null; @@ -115,7 +118,7 @@ class RedisCache implements Cache { }, true); } - + public void evict(Object key) { final byte[] k = computeKey(key); @@ -129,7 +132,7 @@ class RedisCache implements Cache { }, true); } - + public void clear() { // need to del each key individually template.execute(new RedisCallback() { diff --git a/src/main/java/org/springframework/data/redis/cache/RedisCacheManager.java b/src/main/java/org/springframework/data/redis/cache/RedisCacheManager.java index 8de28c475..35a3995da 100644 --- a/src/main/java/org/springframework/data/redis/cache/RedisCacheManager.java +++ b/src/main/java/org/springframework/data/redis/cache/RedisCacheManager.java @@ -18,7 +18,6 @@ package org.springframework.data.redis.cache; import java.util.Collection; import java.util.Collections; -import java.util.HashMap; import java.util.Map; import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ConcurrentMap; @@ -44,9 +43,9 @@ public class RedisCacheManager implements CacheManager { private boolean usePrefix; private RedisCachePrefix cachePrefix = new DefaultRedisCachePrefix(); - // 0 - never expire - private long defaultExpireTime = 0; - private Mapexpires = new HashMap(); + // 0 - never expire + private long defaultExpiration = 0; + private Map expires = null; public RedisCacheManager(RedisTemplate template) { this.template = template; @@ -55,23 +54,31 @@ public class RedisCacheManager implements CacheManager { public Cache getCache(String name) { Cache c = caches.get(name); if (c == null) { - long expire = (expires.containsKey(name)) ? expires.get(name) : defaultExpireTime; - c = new RedisCache(name, (usePrefix ? cachePrefix.prefix(name) : null), template, expire); + long expiration = computeExpiration(name); + c = new RedisCache(name, (usePrefix ? cachePrefix.prefix(name) : null), template, expiration); caches.put(name, c); } return c; } + private long computeExpiration(String name) { + Long expiration = null; + if (expires != null) { + expiration = expires.get(name); + } + return (expiration != null ? expiration.longValue() : defaultExpiration); + } + public Collection getCacheNames() { return names; } - public void setUsePrefix(boolean usePrefix) { - this.usePrefix = usePrefix; - } + public void setUsePrefix(boolean usePrefix) { + this.usePrefix = usePrefix; + } - /** + /** * Sets the cachePrefix. * * @param cachePrefix the cachePrefix to set @@ -80,21 +87,21 @@ public class RedisCacheManager implements CacheManager { this.cachePrefix = cachePrefix; } - /** - * Set default expire time. - * - * @param defaultExpireTime time in ms - */ - public void setDefaultExpireTime(long defaultExpireTime) { - this.defaultExpireTime = defaultExpireTime; - } + /** + * Sets the default expire time (in seconds). + * + * @param defaultExpireTime time in seconds. + */ + public void setDefaultExpiration(long defaultExpireTime) { + this.defaultExpiration = defaultExpireTime; + } - /** - * Set expire time for caches - * - * @param expires time in ms - */ - public void setExpires(Map expires) { - this.expires = expires; - } + /** + * Sets the expire time (in seconds) for cache regions (by key). + * + * @param expires time in seconds + */ + public void setExpires(Map expires) { + this.expires = (expires != null ? new ConcurrentHashMap(expires) : null); + } } \ No newline at end of file diff --git a/src/test/java/org/springframework/data/redis/cache/RedisCacheTest.java b/src/test/java/org/springframework/data/redis/cache/RedisCacheTest.java index 7780e5ce3..527d00270 100644 --- a/src/test/java/org/springframework/data/redis/cache/RedisCacheTest.java +++ b/src/test/java/org/springframework/data/redis/cache/RedisCacheTest.java @@ -60,7 +60,7 @@ public class RedisCacheTest extends AbstractNativeCacheTest { protected Cache createCache(RedisTemplate nativeCache) { - return new RedisCache(CACHE_NAME, CACHE_NAME.concat(":").getBytes(), nativeCache); + return new RedisCache(CACHE_NAME, CACHE_NAME.concat(":").getBytes(), nativeCache, TimeUnit.MINUTES.toSeconds(5)); }