1717
1818import java .lang .reflect .Method ;
1919import java .nio .ByteBuffer ;
20+ import java .time .Duration ;
2021import java .util .Arrays ;
2122import java .util .Collection ;
2223import java .util .Map ;
@@ -93,9 +94,9 @@ protected RedisCache(String name, RedisCacheWriter cacheWriter, RedisCacheConfig
9394
9495
9596 /**
96- * Get {@link RedisCacheConfiguration} used.
97+ * Gets {@link RedisCacheConfiguration} used to configure this cache .
9798 *
98- * @return immutable {@link RedisCacheConfiguration}. Never {@literal null}.
99+ * @return immutable {@link RedisCacheConfiguration} used to configure this cache; never {@literal null}.
99100 */
100101 public RedisCacheConfiguration getCacheConfiguration () {
101102 return this .cacheConfiguration ;
@@ -130,6 +131,15 @@ public CacheStatistics getStatistics() {
130131 return getCacheWriter ().getCacheStatistics (getName ());
131132 }
132133
134+ /**
135+ * Return the {@link TtlFunction} used to compute the per cache entry {@link Duration time to live expiration}.
136+ *
137+ * @return the {@link TtlFunction} used to compute the per cache entry {@link Duration time to live expiration}.
138+ */
139+ protected TtlFunction getTtlFunction () {
140+ return this .ttlFunction ;
141+ }
142+
133143 @ Override
134144 @ SuppressWarnings ("unchecked" )
135145 public <T > T get (Object key , Callable <T > valueLoader ) {
@@ -178,7 +188,7 @@ public void put(Object key, @Nullable Object value) {
178188
179189 Object cacheValue = preProcessCacheValue (value );
180190
181- if (! isAllowNullValues () && cacheValue == null ) {
191+ if (isNonAllowedNullCacheValue ( cacheValue ) ) {
182192
183193 String message = String .format ("Cache '%s' does not allow 'null' values; Avoid storing null"
184194 + " via '@Cacheable(unless=\" #result == null\" )' or configure RedisCache to allow 'null'"
@@ -189,20 +199,20 @@ public void put(Object key, @Nullable Object value) {
189199 }
190200
191201 getCacheWriter ().put (getName (), createAndConvertCacheKey (key ), serializeCacheValue (cacheValue ),
192- ttlFunction . getTimeToLive (key , value ));
202+ getTtlFunction (). computeTimeToLive (key , value ));
193203 }
194204
195205 @ Override
196206 public ValueWrapper putIfAbsent (Object key , @ Nullable Object value ) {
197207
198208 Object cacheValue = preProcessCacheValue (value );
199209
200- if (! isAllowNullValues () && cacheValue == null ) {
210+ if (isNonAllowedNullCacheValue ( cacheValue ) ) {
201211 return get (key );
202212 }
203213
204214 byte [] result = getCacheWriter ().putIfAbsent (getName (), createAndConvertCacheKey (key ),
205- serializeCacheValue (cacheValue ), ttlFunction . getTimeToLive (key , value ));
215+ serializeCacheValue (cacheValue ), getTtlFunction (). computeTimeToLive (key , value ));
206216
207217 return result != null ? new SimpleValueWrapper (fromStoreValue (deserializeCacheValue (result ))) : null ;
208218 }
@@ -320,8 +330,8 @@ protected String createCacheKey(Object key) {
320330 */
321331 protected String convertKey (Object key ) {
322332
323- if (key instanceof String ) {
324- return ( String ) key ;
333+ if (key instanceof String stringKey ) {
334+ return stringKey ;
325335 }
326336
327337 TypeDescriptor source = TypeDescriptor .forObject (key );
@@ -368,6 +378,10 @@ private boolean isCollectionLikeOrMap(TypeDescriptor source) {
368378 return source .isArray () || source .isCollection () || source .isMap ();
369379 }
370380
381+ private boolean isNonAllowedNullCacheValue (@ Nullable Object cacheValue ) {
382+ return cacheValue == null && !isAllowNullValues ();
383+ }
384+
371385 private String convertCollectionLikeOrMapKey (Object key , TypeDescriptor source ) {
372386
373387 if (source .isMap ()) {
0 commit comments