13
13
* See the License for the specific language governing permissions and
14
14
* limitations under the License.
15
15
*/
16
-
17
16
package org .springframework .data .redis .cache ;
18
17
19
18
import static org .springframework .util .Assert .*;
40
39
import org .springframework .data .redis .serializer .JdkSerializationRedisSerializer ;
41
40
import org .springframework .data .redis .serializer .RedisSerializer ;
42
41
import org .springframework .data .redis .serializer .StringRedisSerializer ;
42
+ import org .springframework .util .Assert ;
43
43
import org .springframework .util .ClassUtils ;
44
44
import org .springframework .util .ObjectUtils ;
45
45
54
54
@ SuppressWarnings ("unchecked" )
55
55
public class RedisCache extends AbstractValueAdaptingCache {
56
56
57
- @ SuppressWarnings ("rawtypes" )//
57
+ @ SuppressWarnings ("rawtypes" ) //
58
58
private final RedisOperations redisOperations ;
59
59
private final RedisCacheMetadata cacheMetadata ;
60
60
private final CacheValueAccessor cacheValueAccessor ;
61
61
62
62
/**
63
- * Constructs a new <code> RedisCache</code> instance.
63
+ * Constructs a new {@link RedisCache} instance.
64
64
*
65
65
* @param name cache name
66
66
* @param prefix
@@ -73,10 +73,10 @@ public RedisCache(String name, byte[] prefix, RedisOperations<? extends Object,
73
73
}
74
74
75
75
/**
76
- * Constructs a new <code> RedisCache</code> instance.
76
+ * Constructs a new {@link RedisCache} instance.
77
77
*
78
78
* @param name cache name
79
- * @param prefix
79
+ * @param prefix must not be {@literal null} or empty.
80
80
* @param redisOperations
81
81
* @param expiration
82
82
* @param allowNullValues
@@ -87,15 +87,14 @@ public RedisCache(String name, byte[] prefix, RedisOperations<? extends Object,
87
87
88
88
super (allowNullValues );
89
89
90
- hasText (name , "non-empty cache name is required" );
91
- this .cacheMetadata = new RedisCacheMetadata (name , prefix );
92
- this .cacheMetadata .setDefaultExpiration (expiration );
93
-
94
- this .redisOperations = redisOperations ;
90
+ Assert .hasText (name , "CacheName must not be null or empty!" );
95
91
96
92
RedisSerializer <?> serializer = redisOperations .getValueSerializer () != null ? redisOperations .getValueSerializer ()
97
93
: (RedisSerializer <?>) new JdkSerializationRedisSerializer ();
98
94
95
+ this .cacheMetadata = new RedisCacheMetadata (name , prefix );
96
+ this .cacheMetadata .setDefaultExpiration (expiration );
97
+ this .redisOperations = redisOperations ;
99
98
this .cacheValueAccessor = new CacheValueAccessor (serializer );
100
99
101
100
if (allowNullValues ) {
@@ -105,7 +104,9 @@ public RedisCache(String name, byte[] prefix, RedisOperations<? extends Object,
105
104
|| redisOperations .getValueSerializer () instanceof JacksonJsonRedisSerializer
106
105
|| redisOperations .getValueSerializer () instanceof Jackson2JsonRedisSerializer ) {
107
106
throw new IllegalArgumentException (String .format (
108
- "Redis does not allow keys with null value ¯\\ _(ツ)_/¯. The chosen %s does not support generic type handling and therefore cannot be used with allowNullValues enabled. Please use a different RedisSerializer or disable null value support." ,
107
+ "Redis does not allow keys with null value ¯\\ _(ツ)_/¯. "
108
+ + "The chosen %s does not support generic type handling and therefore cannot be used with allowNullValues enabled. "
109
+ + "Please use a different RedisSerializer or disable null value support." ,
109
110
ClassUtils .getShortName (redisOperations .getValueSerializer ().getClass ())));
110
111
}
111
112
}
@@ -132,8 +133,7 @@ public <T> T get(Object key, Class<T> type) {
132
133
*/
133
134
@ Override
134
135
public ValueWrapper get (Object key ) {
135
- return get (new RedisCacheKey (key ).usePrefix (this .cacheMetadata .getKeyPrefix ()).withKeySerializer (
136
- redisOperations .getKeySerializer ()));
136
+ return get (getRedisCacheKey (key ));
137
137
}
138
138
139
139
/*
@@ -143,9 +143,7 @@ public ValueWrapper get(Object key) {
143
143
public <T > T get (final Object key , final Callable <T > valueLoader ) {
144
144
145
145
BinaryRedisCacheElement rce = new BinaryRedisCacheElement (
146
- new RedisCacheElement (new RedisCacheKey (key ).usePrefix (cacheMetadata .getKeyPrefix ())
147
- .withKeySerializer (redisOperations .getKeySerializer ()), new StoreTranslatingCallable (valueLoader )),
148
- cacheValueAccessor );
146
+ new RedisCacheElement (getRedisCacheKey (key ), new StoreTranslatingCallable (valueLoader )), cacheValueAccessor );
149
147
150
148
ValueWrapper val = get (key );
151
149
if (val != null ) {
@@ -171,7 +169,7 @@ public <T> T get(final Object key, final Callable<T> valueLoader) {
171
169
*/
172
170
public RedisCacheElement get (final RedisCacheKey cacheKey ) {
173
171
174
- notNull (cacheKey , "CacheKey must not be null!" );
172
+ Assert . notNull (cacheKey , "CacheKey must not be null!" );
175
173
176
174
Boolean exists = (Boolean ) redisOperations .execute (new RedisCallback <Boolean >() {
177
175
@@ -195,9 +193,8 @@ public Boolean doInRedis(RedisConnection connection) throws DataAccessException
195
193
@ Override
196
194
public void put (final Object key , final Object value ) {
197
195
198
- put (new RedisCacheElement (new RedisCacheKey (key ).usePrefix (cacheMetadata .getKeyPrefix ())
199
- .withKeySerializer (redisOperations .getKeySerializer ()), toStoreValue (value ))
200
- .expireAfter (cacheMetadata .getDefaultExpiration ()));
196
+ put (new RedisCacheElement (getRedisCacheKey (key ), toStoreValue (value ))
197
+ .expireAfter (cacheMetadata .getDefaultExpiration ()));
201
198
}
202
199
203
200
/*
@@ -225,10 +222,10 @@ protected Object fromStoreValue(Object storeValue) {
225
222
*/
226
223
public void put (RedisCacheElement element ) {
227
224
228
- notNull (element , "Element must not be null!" );
225
+ Assert . notNull (element , "Element must not be null!" );
229
226
230
- redisOperations . execute ( new RedisCachePutCallback ( new BinaryRedisCacheElement ( element , cacheValueAccessor ),
231
- cacheMetadata ));
227
+ redisOperations
228
+ . execute ( new RedisCachePutCallback ( new BinaryRedisCacheElement ( element , cacheValueAccessor ), cacheMetadata ));
232
229
}
233
230
234
231
/*
@@ -237,9 +234,8 @@ public void put(RedisCacheElement element) {
237
234
*/
238
235
public ValueWrapper putIfAbsent (Object key , final Object value ) {
239
236
240
- return putIfAbsent (new RedisCacheElement (new RedisCacheKey (key ).usePrefix (cacheMetadata .getKeyPrefix ())
241
- .withKeySerializer (redisOperations .getKeySerializer ()), toStoreValue (value ))
242
- .expireAfter (cacheMetadata .getDefaultExpiration ()));
237
+ return putIfAbsent (new RedisCacheElement (getRedisCacheKey (key ), toStoreValue (value ))
238
+ .expireAfter (cacheMetadata .getDefaultExpiration ()));
243
239
}
244
240
245
241
/**
@@ -252,22 +248,20 @@ public ValueWrapper putIfAbsent(Object key, final Object value) {
252
248
*/
253
249
public ValueWrapper putIfAbsent (RedisCacheElement element ) {
254
250
255
- notNull (element , "Element must not be null!" );
251
+ Assert . notNull (element , "Element must not be null!" );
256
252
257
253
new RedisCachePutIfAbsentCallback (new BinaryRedisCacheElement (element , cacheValueAccessor ), cacheMetadata );
258
254
259
- return toWrapper (cacheValueAccessor .deserializeIfNecessary ((byte []) redisOperations
260
- .execute (new RedisCachePutIfAbsentCallback (new BinaryRedisCacheElement (element , cacheValueAccessor ),
261
- cacheMetadata ))));
255
+ return toWrapper (cacheValueAccessor .deserializeIfNecessary ((byte []) redisOperations .execute (
256
+ new RedisCachePutIfAbsentCallback (new BinaryRedisCacheElement (element , cacheValueAccessor ), cacheMetadata ))));
262
257
}
263
258
264
259
/*
265
260
* (non-Javadoc)
266
261
* @see org.springframework.cache.Cache#evict(java.lang.Object)
267
262
*/
268
263
public void evict (Object key ) {
269
- evict (new RedisCacheElement (new RedisCacheKey (key ).usePrefix (cacheMetadata .getKeyPrefix ()).withKeySerializer (
270
- redisOperations .getKeySerializer ()), null ));
264
+ evict (new RedisCacheElement (getRedisCacheKey (key ), null ));
271
265
}
272
266
273
267
/**
@@ -276,9 +270,9 @@ public void evict(Object key) {
276
270
*/
277
271
public void evict (final RedisCacheElement element ) {
278
272
279
- notNull (element , "Element must not be null!" );
280
- redisOperations . execute ( new RedisCacheEvictCallback ( new BinaryRedisCacheElement ( element , cacheValueAccessor ),
281
- cacheMetadata ));
273
+ Assert . notNull (element , "Element must not be null!" );
274
+ redisOperations
275
+ . execute ( new RedisCacheEvictCallback ( new BinaryRedisCacheElement ( element , cacheValueAccessor ), cacheMetadata ));
282
276
}
283
277
284
278
/*
@@ -317,9 +311,7 @@ private ValueWrapper toWrapper(Object value) {
317
311
@ Override
318
312
protected Object lookup (Object key ) {
319
313
320
- RedisCacheKey cacheKey = key instanceof RedisCacheKey ? (RedisCacheKey ) key
321
- : new RedisCacheKey (key ).usePrefix (this .cacheMetadata .getKeyPrefix ())
322
- .withKeySerializer (redisOperations .getKeySerializer ());
314
+ RedisCacheKey cacheKey = key instanceof RedisCacheKey ? (RedisCacheKey ) key : getRedisCacheKey (key );
323
315
324
316
byte [] bytes = (byte []) redisOperations .execute (new AbstractRedisCacheCallback <byte []>(
325
317
new BinaryRedisCacheElement (new RedisCacheElement (cacheKey , null ), cacheValueAccessor ), cacheMetadata ) {
@@ -333,6 +325,11 @@ public byte[] doInRedis(BinaryRedisCacheElement element, RedisConnection connect
333
325
return bytes == null ? null : cacheValueAccessor .deserializeIfNecessary (bytes );
334
326
}
335
327
328
+ private RedisCacheKey getRedisCacheKey (Object key ) {
329
+ return new RedisCacheKey (key ).usePrefix (this .cacheMetadata .getKeyPrefix ())
330
+ .withKeySerializer (redisOperations .getKeySerializer ());
331
+ }
332
+
336
333
/**
337
334
* {@link Callable} to transform a value obtained from another {@link Callable} to its store value.
338
335
*
@@ -375,7 +372,7 @@ static class RedisCacheMetadata {
375
372
*/
376
373
public RedisCacheMetadata (String cacheName , byte [] keyPrefix ) {
377
374
378
- hasText (cacheName , "CacheName must not be null or empty!" );
375
+ Assert . hasText (cacheName , "CacheName must not be null or empty!" );
379
376
this .cacheName = cacheName ;
380
377
this .keyPrefix = keyPrefix ;
381
378
@@ -431,8 +428,8 @@ public String getCacheName() {
431
428
432
429
/**
433
430
* Set the default expiration time in seconds
434
- *
435
- * @param defaultExpiration
431
+ *
432
+ * @param seconds
436
433
*/
437
434
public void setDefaultExpiration (long seconds ) {
438
435
this .defaultExpiration = seconds ;
@@ -455,7 +452,7 @@ public long getDefaultExpiration() {
455
452
*/
456
453
static class CacheValueAccessor {
457
454
458
- @ SuppressWarnings ("rawtypes" )//
455
+ @ SuppressWarnings ("rawtypes" ) //
459
456
private final RedisSerializer valueSerializer ;
460
457
461
458
@ SuppressWarnings ("rawtypes" )
@@ -687,8 +684,8 @@ public Void doInLock(RedisConnection connection) {
687
684
688
685
do {
689
686
// need to paginate the keys
690
- Set <byte []> keys = connection .zRange (metadata .getSetOfKnownKeysKey (), (offset ) * PAGE_SIZE , ( offset + 1 )
691
- * PAGE_SIZE - 1 );
687
+ Set <byte []> keys = connection .zRange (metadata .getSetOfKnownKeysKey (), (offset ) * PAGE_SIZE ,
688
+ ( offset + 1 ) * PAGE_SIZE - 1 );
692
689
finished = keys .size () < PAGE_SIZE ;
693
690
offset ++;
694
691
if (!keys .isEmpty ()) {
@@ -707,8 +704,8 @@ public Void doInLock(RedisConnection connection) {
707
704
*/
708
705
static class RedisCacheCleanByPrefixCallback extends LockingRedisCacheCallback <Void > {
709
706
710
- private static final byte [] REMOVE_KEYS_BY_PATTERN_LUA = new StringRedisSerializer ()
711
- . serialize ( "local keys = redis.call('KEYS', ARGV[1]); local keysCount = table.getn(keys); if(keysCount > 0) then for _, key in ipairs(keys) do redis.call('del', key); end; end; return keysCount;" );
707
+ private static final byte [] REMOVE_KEYS_BY_PATTERN_LUA = new StringRedisSerializer (). serialize (
708
+ "local keys = redis.call('KEYS', ARGV[1]); local keysCount = table.getn(keys); if(keysCount > 0) then for _, key in ipairs(keys) do redis.call('del', key); end; end; return keysCount;" );
712
709
private static final byte [] WILD_CARD = new StringRedisSerializer ().serialize ("*" );
713
710
private final RedisCacheMetadata metadata ;
714
711
@@ -727,7 +724,7 @@ public Void doInLock(RedisConnection connection) throws DataAccessException {
727
724
byte [] prefixToUse = Arrays .copyOf (metadata .getKeyPrefix (), metadata .getKeyPrefix ().length + WILD_CARD .length );
728
725
System .arraycopy (WILD_CARD , 0 , prefixToUse , metadata .getKeyPrefix ().length , WILD_CARD .length );
729
726
730
- if (isClusterConnection (connection )) {
727
+ if (isClusterConnection (connection )) {
731
728
732
729
// load keys to the client because currently Redis Cluster connections do not allow eval of lua scripts.
733
730
Set <byte []> keys = connection .keys (prefixToUse );
@@ -913,8 +910,8 @@ public RuntimeException create(Object key, Callable<?> valueLoader, Throwable ca
913
910
914
911
if (isSpring43 ) {
915
912
try {
916
- Class <?> execption = ClassUtils .forName ("org.springframework.cache.Cache$ValueRetrievalException" , this
917
- .getClass ().getClassLoader ());
913
+ Class <?> execption = ClassUtils .forName ("org.springframework.cache.Cache$ValueRetrievalException" ,
914
+ this .getClass ().getClassLoader ());
918
915
Constructor <?> c = ClassUtils .getConstructorIfAvailable (execption , Object .class , Callable .class ,
919
916
Throwable .class );
920
917
return (RuntimeException ) c .newInstance (key , valueLoader , cause );
@@ -923,8 +920,8 @@ public RuntimeException create(Object key, Callable<?> valueLoader, Throwable ca
923
920
}
924
921
}
925
922
926
- return new RedisSystemException (String . format ( "Value for key '%s' could not be loaded using '%s'." , key ,
927
- valueLoader ), cause );
923
+ return new RedisSystemException (
924
+ String . format ( "Value for key '%s' could not be loaded using '%s'." , key , valueLoader ), cause );
928
925
}
929
926
}
930
927
0 commit comments