47
47
public class RedisCacheConfiguration {
48
48
49
49
protected static final boolean DEFAULT_CACHE_NULL_VALUES = true ;
50
+ protected static final boolean DEFAULT_ENABLE_TTI_EXPIRATION = false ;
50
51
protected static final boolean DEFAULT_USE_PREFIX = true ;
51
52
protected static final boolean DO_NOT_CACHE_NULL_VALUES = false ;
52
53
protected static final boolean DO_NOT_USE_PREFIX = false ;
54
+ protected static final boolean ENABLE_IDLE_TIME_EXPIRATION = true ;
53
55
54
56
/**
55
57
* Default {@link RedisCacheConfiguration} using the following:
@@ -108,14 +110,18 @@ public static RedisCacheConfiguration defaultCacheConfig(@Nullable ClassLoader c
108
110
109
111
registerDefaultConverters (conversionService );
110
112
111
- return new RedisCacheConfiguration (TtlFunction .persistent (), DEFAULT_CACHE_NULL_VALUES , DEFAULT_USE_PREFIX ,
113
+ return new RedisCacheConfiguration (TtlFunction .persistent (),
114
+ DEFAULT_CACHE_NULL_VALUES ,
115
+ DEFAULT_ENABLE_TTI_EXPIRATION ,
116
+ DEFAULT_USE_PREFIX ,
112
117
CacheKeyPrefix .simple (),
113
118
SerializationPair .fromSerializer (RedisSerializer .string ()),
114
119
SerializationPair .fromSerializer (RedisSerializer .java (classLoader )),
115
120
conversionService );
116
121
}
117
122
118
123
private final boolean cacheNullValues ;
124
+ private final boolean enableTtiExpiration ;
119
125
private final boolean usePrefix ;
120
126
121
127
private final CacheKeyPrefix keyPrefix ;
@@ -128,12 +134,13 @@ public static RedisCacheConfiguration defaultCacheConfig(@Nullable ClassLoader c
128
134
private final TtlFunction ttlFunction ;
129
135
130
136
@ SuppressWarnings ("unchecked" )
131
- private RedisCacheConfiguration (TtlFunction ttlFunction , Boolean cacheNullValues , Boolean usePrefix ,
132
- CacheKeyPrefix keyPrefix , SerializationPair <String > keySerializationPair ,
137
+ private RedisCacheConfiguration (TtlFunction ttlFunction , Boolean cacheNullValues , Boolean enableTtiExpiration ,
138
+ Boolean usePrefix , CacheKeyPrefix keyPrefix , SerializationPair <String > keySerializationPair ,
133
139
SerializationPair <?> valueSerializationPair , ConversionService conversionService ) {
134
140
135
141
this .ttlFunction = ttlFunction ;
136
142
this .cacheNullValues = cacheNullValues ;
143
+ this .enableTtiExpiration = enableTtiExpiration ;
137
144
this .usePrefix = usePrefix ;
138
145
this .keyPrefix = keyPrefix ;
139
146
this .keySerializationPair = keySerializationPair ;
@@ -168,8 +175,9 @@ public RedisCacheConfiguration computePrefixWith(CacheKeyPrefix cacheKeyPrefix)
168
175
169
176
Assert .notNull (cacheKeyPrefix , "Function used to compute prefix must not be null" );
170
177
171
- return new RedisCacheConfiguration (getTtlFunction (), getAllowCacheNullValues (), DEFAULT_USE_PREFIX ,
172
- cacheKeyPrefix , getKeySerializationPair (), getValueSerializationPair (), getConversionService ());
178
+ return new RedisCacheConfiguration (getTtlFunction (), getAllowCacheNullValues (), isTtiExpirationEnabled (),
179
+ DEFAULT_USE_PREFIX , cacheKeyPrefix , getKeySerializationPair (), getValueSerializationPair (),
180
+ getConversionService ());
173
181
}
174
182
175
183
/**
@@ -181,8 +189,9 @@ public RedisCacheConfiguration computePrefixWith(CacheKeyPrefix cacheKeyPrefix)
181
189
* @return new {@link RedisCacheConfiguration}.
182
190
*/
183
191
public RedisCacheConfiguration disableCachingNullValues () {
184
- return new RedisCacheConfiguration (getTtlFunction (), DO_NOT_CACHE_NULL_VALUES , usePrefix (), getKeyPrefix (),
185
- getKeySerializationPair (), getValueSerializationPair (), getConversionService ());
192
+ return new RedisCacheConfiguration (getTtlFunction (), DO_NOT_CACHE_NULL_VALUES , isTtiExpirationEnabled (),
193
+ usePrefix (), getKeyPrefix (), getKeySerializationPair (), getValueSerializationPair (),
194
+ getConversionService ());
186
195
}
187
196
188
197
/**
@@ -193,8 +202,30 @@ public RedisCacheConfiguration disableCachingNullValues() {
193
202
* @return new {@link RedisCacheConfiguration}.
194
203
*/
195
204
public RedisCacheConfiguration disableKeyPrefix () {
196
- return new RedisCacheConfiguration (getTtlFunction (), getAllowCacheNullValues (), DO_NOT_USE_PREFIX ,
197
- getKeyPrefix (), getKeySerializationPair (), getValueSerializationPair (), getConversionService ());
205
+ return new RedisCacheConfiguration (getTtlFunction (), getAllowCacheNullValues (), isTtiExpirationEnabled (),
206
+ DO_NOT_USE_PREFIX , getKeyPrefix (), getKeySerializationPair (), getValueSerializationPair (), getConversionService ());
207
+ }
208
+
209
+ /**
210
+ * Enables {@literal time-to-idle (TTI) expiration} on {@link Cache} read operations,
211
+ * such as {@link Cache#get(Object)}.
212
+ * <p>
213
+ * Enabling this option applies the same {@link #getTtlFunction() TTL expiration policy} to {@link Cache} read
214
+ * operations as it does for {@link Cache} write operations. In effect, this will invoke the Redis {@literal GETEX}
215
+ * command in place of {@literal GET}.
216
+ * <p>
217
+ * Redis does not support the concept of {@literal TTI}, only {@literal TTL}. However, if {@literal TTL} expiration
218
+ * is applied to all {@link Cache} operations, both read and write alike, and {@link Cache} operations passed with
219
+ * expiration are used consistently across the application, then in effect, an application can achieve
220
+ * {@literal TTI} expiration-like behavior.
221
+ *
222
+ * @return this {@link RedisCacheConfiguration}.
223
+ * @see <a href="https://redis.io/commands/getex/">GETEX</a>
224
+ */
225
+ public RedisCacheConfiguration enableTtiExpiration () {
226
+ return new RedisCacheConfiguration (getTtlFunction (), getAllowCacheNullValues (), ENABLE_IDLE_TIME_EXPIRATION ,
227
+ usePrefix (), getKeyPrefix (), getKeySerializationPair (), getValueSerializationPair (),
228
+ getConversionService ());
198
229
}
199
230
200
231
/**
@@ -222,8 +253,9 @@ public RedisCacheConfiguration entryTtl(TtlFunction ttlFunction) {
222
253
223
254
Assert .notNull (ttlFunction , "TtlFunction must not be null" );
224
255
225
- return new RedisCacheConfiguration (ttlFunction , getAllowCacheNullValues (), usePrefix (), getKeyPrefix (),
226
- getKeySerializationPair (), getValueSerializationPair (), getConversionService ());
256
+ return new RedisCacheConfiguration (ttlFunction , getAllowCacheNullValues (), isTtiExpirationEnabled (),
257
+ usePrefix (), getKeyPrefix (), getKeySerializationPair (), getValueSerializationPair (),
258
+ getConversionService ());
227
259
}
228
260
229
261
/**
@@ -236,8 +268,8 @@ public RedisCacheConfiguration serializeKeysWith(SerializationPair<String> keySe
236
268
237
269
Assert .notNull (keySerializationPair , "KeySerializationPair must not be null" );
238
270
239
- return new RedisCacheConfiguration (getTtlFunction (), getAllowCacheNullValues (), usePrefix (), getKeyPrefix (),
240
- keySerializationPair , getValueSerializationPair (), getConversionService ());
271
+ return new RedisCacheConfiguration (getTtlFunction (), getAllowCacheNullValues (), isTtiExpirationEnabled (),
272
+ usePrefix (), getKeyPrefix (), keySerializationPair , getValueSerializationPair (), getConversionService ());
241
273
}
242
274
243
275
/**
@@ -250,8 +282,8 @@ public RedisCacheConfiguration serializeValuesWith(SerializationPair<?> valueSer
250
282
251
283
Assert .notNull (valueSerializationPair , "ValueSerializationPair must not be null" );
252
284
253
- return new RedisCacheConfiguration (getTtlFunction (), getAllowCacheNullValues (), usePrefix (), getKeyPrefix (),
254
- getKeySerializationPair (), valueSerializationPair , getConversionService ());
285
+ return new RedisCacheConfiguration (getTtlFunction (), getAllowCacheNullValues (), isTtiExpirationEnabled (),
286
+ usePrefix (), getKeyPrefix (), getKeySerializationPair (), valueSerializationPair , getConversionService ());
255
287
}
256
288
257
289
/**
@@ -264,8 +296,8 @@ public RedisCacheConfiguration withConversionService(ConversionService conversio
264
296
265
297
Assert .notNull (conversionService , "ConversionService must not be null" );
266
298
267
- return new RedisCacheConfiguration (getTtlFunction (), getAllowCacheNullValues (), usePrefix (), getKeyPrefix (),
268
- getKeySerializationPair (), getValueSerializationPair (), conversionService );
299
+ return new RedisCacheConfiguration (getTtlFunction (), getAllowCacheNullValues (), isTtiExpirationEnabled (),
300
+ usePrefix (), getKeyPrefix (), getKeySerializationPair (), getValueSerializationPair (), conversionService );
269
301
}
270
302
271
303
/**
@@ -275,6 +307,19 @@ public boolean getAllowCacheNullValues() {
275
307
return this .cacheNullValues ;
276
308
}
277
309
310
+ /**
311
+ * Determines whether {@literal time-to-idle (TTI) expiration} has been enabled for caching.
312
+ * <p>
313
+ * Use {@link #enableTtiExpiration()} to opt-in and enable {@literal time-to-idle (TTI) expiration} for caching.
314
+ *
315
+ * @return {@literal true} if {@literal time-to-idle (TTI) expiration} was configured and enabled for caching.
316
+ * Defaults to {@literal false}.
317
+ * @see <a href="https://redis.io/commands/getex/">GETEX</a>
318
+ */
319
+ public boolean isTtiExpirationEnabled () {
320
+ return this .enableTtiExpiration ;
321
+ }
322
+
278
323
/**
279
324
* @return {@literal true} if cache keys need to be prefixed with the {@link #getKeyPrefixFor(String)} if present or
280
325
* the default which resolves to {@link Cache#getName()}.
0 commit comments