-
Notifications
You must be signed in to change notification settings - Fork 38.6k
Description
The automatic configuration of a cache is amazing for the simple cases, however quickly becomes weird if you decide to use multiple CacheManager
instances.
For example you might want to have a Distributed Cache using Redis, and a Local Caffeine or ConcurrentMap Cache for small items, you'd need the following configuration.
@Configuration
@EnableCaching
public CachingConfig implements CachingConfigurer, ApplicationContextAware {
private ApplicationContext ac;
@Bean
public CacheManager redisCacheManager(RedisConnectionFactory factory, CacheProperties props) {
// Implementing Redis Cache
}
@Bean
public CacheManager caffeineCache(CacheProperties cacheProperties) {
// Implementing Caffeine Cache
}
@Override
@Bean
public CacheResolver cacheResolver() {
var redisCache = ac.getBean("redisCacheManager", CacheManager.class);
var caffeineCache = ac.getBean("caffeineCache", CacheManager.class);
// Implement Resolver
}
@Override
public KeyGenerator keyGenerator() {
return new SimpleKeyGenerator();
}
@Override
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
this.ac= applicationContext;
}
}
From a user perspective there are some parts that are a little verbose compared to other configurations. Highlights would be bringing in the ApplicationContext
, but the class really doesn't care for it, implementing the KeyGenerator
using the same default Spring does (per CachingConfigurer Docs), and then not overriding CachingConfigurer::cacheManager()
for a mixture of reasons.
I personally I think Caching could use a more "Default unless Declared" approach, where we could reduce this down to the following.
@Configuration
@EnableCaching
public CachingConfig {
@Bean
public CacheManager redisCacheManager(RedisConnectionFactory factory, CacheProperties props) {
// Implementing Redis Cache
}
@Bean
public CacheManager caffeineCache(CacheProperties cacheProperties) {
// Implementing Caffeine Cache
}
@Bean
public CacheResolver cacheResolver(
@Qualifier("redisCacheManager") CacheManager redis,
@Qualifier("caffeineCache") CacheManager caffeine
) {
// Implement Resolver
}
}
This removes the KeyGenerator
, swaps ApplicationContext::getBean
with Parameter Injection, and removes the CachingConfigurer
in favor of global bean detection. What other adjustments would the Spring Boot Team be open to?