0
# Cache Configuration
1
2
Spring Boot's cache configuration provides comprehensive auto-configuration for caching providers including Redis, Caffeine, EhCache, and Hazelcast with Spring's cache abstraction.
3
4
## Capabilities
5
6
### Cache Abstraction Configuration
7
8
Auto-configuration for Spring's cache abstraction with support for multiple cache providers.
9
10
```java { .api }
11
/**
12
* Auto-configuration for Spring Cache abstraction
13
* Provides cache management infrastructure and automatic provider detection
14
*/
15
@AutoConfiguration
16
@ConditionalOnClass(CacheManager.class)
17
@ConditionalOnBean(CacheAspectSupport.class)
18
@ConditionalOnProperty(prefix = "spring.cache", name = "type")
19
@EnableConfigurationProperties(CacheProperties.class)
20
@AutoConfigureAfter({CouchbaseAutoConfiguration.class, HazelcastAutoConfiguration.class,
21
HibernateJpaAutoConfiguration.class, RedisAutoConfiguration.class})
22
@Import({CacheConfigurationImportSelector.class, CacheManagerEntityManagerFactoryDependsOnPostProcessor.class})
23
public class CacheAutoConfiguration {
24
25
/**
26
* Cache manager validator to ensure exactly one cache manager is configured
27
*/
28
@Bean
29
@ConditionalOnMissingBean
30
public CacheManagerValidator cacheAutoConfigurationValidator() {
31
return new CacheManagerValidator();
32
}
33
34
/**
35
* Cache manager customizer beans collector
36
*/
37
@Bean
38
public CacheManagerCustomizers cacheManagerCustomizers(
39
ObjectProvider<CacheManagerCustomizer<?>> customizers) {
40
return new CacheManagerCustomizers(customizers.orderedStream().collect(Collectors.toList()));
41
}
42
43
/**
44
* Cache resolver for programmatic cache resolution
45
*/
46
@Bean
47
@ConditionalOnMissingBean
48
public CacheResolver cacheResolver(CacheManager cacheManager) {
49
return new SimpleCacheResolver(cacheManager);
50
}
51
52
/**
53
* Key generator for cache keys
54
*/
55
@Bean
56
@ConditionalOnMissingBean
57
public KeyGenerator keyGenerator() {
58
return new SimpleKeyGenerator();
59
}
60
}
61
62
/**
63
* Cache configuration properties
64
*/
65
@ConfigurationProperties(prefix = "spring.cache")
66
public class CacheProperties {
67
68
/**
69
* Cache type to use
70
*/
71
private CacheType type;
72
73
/**
74
* Comma-separated list of cache names to create if supported by the underlying cache manager
75
*/
76
private List<String> cacheNames = new ArrayList<>();
77
78
/**
79
* Caffeine cache configuration
80
*/
81
private final Caffeine caffeine = new Caffeine();
82
83
/**
84
* Cache2k cache configuration
85
*/
86
private final Cache2k cache2k = new Cache2k();
87
88
/**
89
* EhCache configuration
90
*/
91
private final Ehcache ehcache = new Ehcache();
92
93
/**
94
* Hazelcast configuration
95
*/
96
private final Hazelcast hazelcast = new Hazelcast();
97
98
/**
99
* Infinispan configuration
100
*/
101
private final Infinispan infinispan = new Infinispan();
102
103
/**
104
* JCache configuration
105
*/
106
private final JCache jcache = new JCache();
107
108
/**
109
* Redis cache configuration
110
*/
111
private final Redis redis = new Redis();
112
113
// Getters and setters
114
public CacheType getType() { return this.type; }
115
public void setType(CacheType type) { this.type = type; }
116
public List<String> getCacheNames() { return this.cacheNames; }
117
public void setCacheNames(List<String> cacheNames) { this.cacheNames = cacheNames; }
118
119
/**
120
* Caffeine cache configuration
121
*/
122
public static class Caffeine {
123
/**
124
* Cache specification string for Caffeine
125
*/
126
private String spec;
127
128
public String getSpec() { return this.spec; }
129
public void setSpec(String spec) { this.spec = spec; }
130
}
131
132
/**
133
* Redis cache configuration
134
*/
135
public static class Redis {
136
/**
137
* Entry expiration time
138
*/
139
private Duration timeToLive;
140
141
/**
142
* Whether to allow caching null values
143
*/
144
private boolean cacheNullValues = true;
145
146
/**
147
* Key prefix to use
148
*/
149
private String keyPrefix;
150
151
/**
152
* Whether to use key prefix
153
*/
154
private boolean useKeyPrefix = true;
155
156
/**
157
* Whether to enable statistics
158
*/
159
private boolean enableStatistics;
160
161
// Getters and setters
162
public Duration getTimeToLive() { return this.timeToLive; }
163
public void setTimeToLive(Duration timeToLive) { this.timeToLive = timeToLive; }
164
public boolean isCacheNullValues() { return this.cacheNullValues; }
165
public void setCacheNullValues(boolean cacheNullValues) { this.cacheNullValues = cacheNullValues; }
166
public String getKeyPrefix() { return this.keyPrefix; }
167
public void setKeyPrefix(String keyPrefix) { this.keyPrefix = keyPrefix; }
168
}
169
170
/**
171
* Supported cache types
172
*/
173
public enum CacheType {
174
GENERIC, JCACHE, EHCACHE, HAZELCAST, INFINISPAN, COUCHBASE, REDIS, CAFFEINE, CACHE2K, SIMPLE, NONE
175
}
176
}
177
```
178
179
### Redis Cache Configuration
180
181
Auto-configuration for Redis-backed caching.
182
183
```java { .api }
184
/**
185
* Auto-configuration for Redis cache
186
* Configures Redis as a cache provider with Spring's cache abstraction
187
*/
188
@AutoConfiguration
189
@ConditionalOnClass({RedisTemplate.class})
190
@AutoConfigureAfter(RedisAutoConfiguration.class)
191
@ConditionalOnBean(RedisConnectionFactory.class)
192
@ConditionalOnMissingBean(CacheManager.class)
193
@Conditional(CacheCondition.class)
194
@EnableConfigurationProperties(CacheProperties.class)
195
public class RedisCacheConfiguration {
196
197
/**
198
* Redis cache manager
199
*/
200
@Bean
201
public RedisCacheManager cacheManager(RedisConnectionFactory redisConnectionFactory,
202
CacheProperties cacheProperties,
203
CacheManagerCustomizers customizers,
204
ObjectProvider<org.springframework.data.redis.cache.RedisCacheConfiguration> redisCacheConfiguration,
205
ObjectProvider<RedisCacheManagerBuilderCustomizer> redisCacheManagerBuilderCustomizers,
206
ResourceLoader resourceLoader) {
207
208
RedisCacheManager.Builder builder = RedisCacheManager
209
.RedisCacheManagerBuilder
210
.fromConnectionFactory(redisConnectionFactory)
211
.cacheDefaults(determineConfiguration(cacheProperties, redisCacheConfiguration, resourceLoader.getClassLoader()));
212
213
List<String> cacheNames = cacheProperties.getCacheNames();
214
if (!cacheNames.isEmpty()) {
215
builder.initialCacheNames(new LinkedHashSet<>(cacheNames));
216
}
217
218
redisCacheManagerBuilderCustomizers.orderedStream().forEach(customizer -> customizer.customize(builder));
219
220
return customizers.customize(builder.build());
221
}
222
223
private org.springframework.data.redis.cache.RedisCacheConfiguration determineConfiguration(
224
CacheProperties cacheProperties,
225
ObjectProvider<org.springframework.data.redis.cache.RedisCacheConfiguration> redisCacheConfiguration,
226
ClassLoader classLoader) {
227
228
return redisCacheConfiguration.getIfAvailable(() -> createConfiguration(cacheProperties, classLoader));
229
}
230
231
private org.springframework.data.redis.cache.RedisCacheConfiguration createConfiguration(
232
CacheProperties cacheProperties, ClassLoader classLoader) {
233
234
Redis redisProperties = cacheProperties.getRedis();
235
org.springframework.data.redis.cache.RedisCacheConfiguration config = org.springframework.data.redis.cache.RedisCacheConfiguration
236
.defaultCacheConfig();
237
238
config = config.serializeValuesWith(RedisSerializationContext.SerializationPair
239
.fromSerializer(new GenericJackson2JsonRedisSerializer()));
240
241
if (redisProperties.getTimeToLive() != null) {
242
config = config.entryTtl(redisProperties.getTimeToLive());
243
}
244
245
if (redisProperties.getKeyPrefix() != null) {
246
config = config.prefixCacheNameWith(redisProperties.getKeyPrefix());
247
}
248
249
if (!redisProperties.isCacheNullValues()) {
250
config = config.disableCachingNullValues();
251
}
252
253
if (!redisProperties.isUseKeyPrefix()) {
254
config = config.disableKeyPrefix();
255
}
256
257
return config;
258
}
259
}
260
```
261
262
### Caffeine Cache Configuration
263
264
Auto-configuration for Caffeine high-performance caching library.
265
266
```java { .api }
267
/**
268
* Auto-configuration for Caffeine cache
269
* Configures Caffeine as a cache provider with high-performance in-memory caching
270
*/
271
@AutoConfiguration
272
@ConditionalOnClass({Caffeine.class, CaffeineCacheManager.class})
273
@ConditionalOnMissingBean(CacheManager.class)
274
@Conditional(CacheCondition.class)
275
@EnableConfigurationProperties(CacheProperties.class)
276
public class CaffeineCacheConfiguration {
277
278
/**
279
* Caffeine cache manager
280
*/
281
@Bean
282
public CaffeineCacheManager cacheManager(CacheProperties cacheProperties,
283
CacheManagerCustomizers customizers,
284
ObjectProvider<Caffeine<Object, Object>> caffeine,
285
ObjectProvider<CaffeineSpec> caffeineSpec,
286
ObjectProvider<CacheLoader<Object, Object>> cacheLoader) {
287
288
CaffeineCacheManager cacheManager = createCacheManager(cacheProperties, caffeine, caffeineSpec, cacheLoader);
289
List<String> cacheNames = cacheProperties.getCacheNames();
290
if (!cacheNames.isEmpty()) {
291
cacheManager.setCacheNames(cacheNames);
292
}
293
return customizers.customize(cacheManager);
294
}
295
296
private CaffeineCacheManager createCacheManager(CacheProperties cacheProperties,
297
ObjectProvider<Caffeine<Object, Object>> caffeine,
298
ObjectProvider<CaffeineSpec> caffeineSpec,
299
ObjectProvider<CacheLoader<Object, Object>> cacheLoader) {
300
301
CaffeineCacheManager cacheManager = new CaffeineCacheManager();
302
setCacheBuilder(cacheProperties, caffeine, caffeineSpec, cacheManager);
303
cacheLoader.ifAvailable(cacheManager::setCacheLoader);
304
return cacheManager;
305
}
306
307
private void setCacheBuilder(CacheProperties cacheProperties,
308
ObjectProvider<Caffeine<Object, Object>> caffeine,
309
ObjectProvider<CaffeineSpec> caffeineSpec,
310
CaffeineCacheManager cacheManager) {
311
312
String specification = cacheProperties.getCaffeine().getSpec();
313
if (StringUtils.hasText(specification)) {
314
cacheManager.setCacheSpecification(specification);
315
} else {
316
caffeine.ifAvailable(cacheManager::setCaffeine);
317
caffeineSpec.ifAvailable(cacheManager::setCaffeineSpec);
318
}
319
}
320
}
321
```
322
323
### EhCache Configuration
324
325
Auto-configuration for EhCache caching provider.
326
327
```java { .api }
328
/**
329
* Auto-configuration for EhCache
330
* Configures EhCache as a cache provider with XML or programmatic configuration
331
*/
332
@AutoConfiguration
333
@ConditionalOnClass({Cache.class, EhCacheCacheManager.class})
334
@ConditionalOnMissingBean(CacheManager.class)
335
@Conditional(CacheCondition.class)
336
@EnableConfigurationProperties(CacheProperties.class)
337
public class EhCacheCacheConfiguration {
338
339
/**
340
* EhCache cache manager
341
*/
342
@Bean
343
public EhCacheCacheManager cacheManager(CacheProperties cacheProperties,
344
CacheManagerCustomizers customizers,
345
ObjectProvider<org.ehcache.config.Configuration> configuration,
346
ResourceLoader resourceLoader) throws IOException {
347
348
Resource configLocation = cacheProperties.resolveConfigLocation(resourceLoader);
349
if (configLocation != null) {
350
return customizers.customize(EhCacheCacheManager.create(configLocation.getInputStream()));
351
}
352
353
return customizers.customize(new EhCacheCacheManager(
354
configuration.getIfAvailable(() -> {
355
CacheConfigurationBuilder<Object, Object> cacheConfiguration = CacheConfigurationBuilder
356
.newCacheConfigurationBuilder(Object.class, Object.class,
357
ResourcePoolsBuilder.heap(1000));
358
return ConfigurationBuilder.newConfigurationBuilder()
359
.withCache("default", cacheConfiguration)
360
.build();
361
})));
362
}
363
}
364
```
365
366
**Usage Examples:**
367
368
```java
369
// Service with caching annotations
370
@Service
371
public class UserService {
372
373
@Cacheable(value = "users", key = "#id")
374
public User findById(Long id) {
375
// Expensive database lookup
376
return userRepository.findById(id).orElse(null);
377
}
378
379
@Cacheable(value = "users", key = "#username")
380
public User findByUsername(String username) {
381
return userRepository.findByUsername(username).orElse(null);
382
}
383
384
@CachePut(value = "users", key = "#user.id")
385
public User updateUser(User user) {
386
return userRepository.save(user);
387
}
388
389
@CacheEvict(value = "users", key = "#id")
390
public void deleteUser(Long id) {
391
userRepository.deleteById(id);
392
}
393
394
@CacheEvict(value = "users", allEntries = true)
395
public void clearUserCache() {
396
// Clears all entries from users cache
397
}
398
}
399
400
// Custom cache configuration
401
@Configuration
402
@EnableCaching
403
public class CacheConfig {
404
405
@Bean
406
public CacheManager cacheManager(RedisConnectionFactory redisConnectionFactory) {
407
RedisCacheConfiguration config = RedisCacheConfiguration.defaultCacheConfig()
408
.entryTtl(Duration.ofMinutes(30))
409
.serializeKeysWith(RedisSerializationContext.SerializationPair.fromSerializer(new StringRedisSerializer()))
410
.serializeValuesWith(RedisSerializationContext.SerializationPair.fromSerializer(new GenericJackson2JsonRedisSerializer()))
411
.disableCachingNullValues();
412
413
return RedisCacheManager.builder(redisConnectionFactory)
414
.cacheDefaults(config)
415
.build();
416
}
417
418
@Bean
419
public KeyGenerator keyGenerator() {
420
return new SimpleKeyGenerator();
421
}
422
423
@Bean
424
public CacheResolver cacheResolver(CacheManager cacheManager) {
425
return new SimpleCacheResolver(cacheManager);
426
}
427
}
428
429
// Programmatic cache usage
430
@Service
431
public class ProductService {
432
433
private final CacheManager cacheManager;
434
435
public ProductService(CacheManager cacheManager) {
436
this.cacheManager = cacheManager;
437
}
438
439
public Product getProduct(Long id) {
440
Cache cache = cacheManager.getCache("products");
441
if (cache != null) {
442
Product cachedProduct = cache.get(id, Product.class);
443
if (cachedProduct != null) {
444
return cachedProduct;
445
}
446
}
447
448
Product product = productRepository.findById(id).orElse(null);
449
if (product != null && cache != null) {
450
cache.put(id, product);
451
}
452
453
return product;
454
}
455
456
public void evictProduct(Long id) {
457
Cache cache = cacheManager.getCache("products");
458
if (cache != null) {
459
cache.evict(id);
460
}
461
}
462
}
463
464
// Custom cache key generator
465
@Component
466
public class CustomKeyGenerator implements KeyGenerator {
467
468
@Override
469
public Object generate(Object target, Method method, Object... params) {
470
StringBuilder key = new StringBuilder();
471
key.append(target.getClass().getSimpleName()).append(".");
472
key.append(method.getName()).append(":");
473
474
for (Object param : params) {
475
key.append(param.toString()).append(",");
476
}
477
478
return key.toString();
479
}
480
}
481
482
// Properties configuration
483
# application.properties
484
# General cache configuration
485
spring.cache.type=redis
486
spring.cache.cache-names=users,products,orders
487
488
# Redis cache configuration
489
spring.cache.redis.time-to-live=600000
490
spring.cache.redis.cache-null-values=false
491
spring.cache.redis.key-prefix=myapp:
492
spring.cache.redis.use-key-prefix=true
493
494
# Caffeine cache configuration
495
spring.cache.caffeine.spec=maximumSize=1000,expireAfterWrite=600s
496
497
# EhCache configuration
498
spring.cache.ehcache.config=classpath:ehcache.xml
499
```
500
501
## Types
502
503
### Cache Configuration Types
504
505
```java { .api }
506
/**
507
* Cache manager customizer interface
508
*/
509
@FunctionalInterface
510
public interface CacheManagerCustomizer<T extends CacheManager> {
511
/**
512
* Customize the cache manager
513
* @param cacheManager the cache manager to customize
514
*/
515
void customize(T cacheManager);
516
}
517
518
/**
519
* Redis cache manager builder customizer
520
*/
521
@FunctionalInterface
522
public interface RedisCacheManagerBuilderCustomizer {
523
/**
524
* Customize the Redis cache manager builder
525
* @param builder the builder to customize
526
*/
527
void customize(RedisCacheManager.RedisCacheManagerBuilder builder);
528
}
529
530
/**
531
* Cache resolver interface for resolving caches at runtime
532
*/
533
public interface CacheResolver {
534
/**
535
* Resolve caches for the given context
536
* @param context the cache operation context
537
* @return collection of caches
538
*/
539
Collection<? extends Cache> resolveCaches(CacheOperationInvocationContext<?> context);
540
}
541
542
/**
543
* Key generator interface for generating cache keys
544
*/
545
public interface KeyGenerator {
546
/**
547
* Generate a cache key
548
* @param target the target instance
549
* @param method the method being called
550
* @param params the method parameters
551
* @return generated key
552
*/
553
Object generate(Object target, Method method, Object... params);
554
}
555
556
/**
557
* Cache condition interface for conditional caching
558
*/
559
public interface CacheCondition {
560
/**
561
* Evaluate if caching should be applied
562
* @param context the evaluation context
563
* @return true if caching should be applied
564
*/
565
boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata);
566
}
567
```