springspring-bootcachingapplicationcontextcaffeine

How to get CaffeineCacheManager from application context in SpringBoot?


I want to use custom WrappingCacheManager as a decorator for CaffeineCacheManager.

Currently configuration is created imperatively with Caffeine.newBuilder()..., and I want to replace it with a declarative version using a property:

spring.cache.caffeine.spec=maximumSize=500, expireAfterWrite=60s

Unfortunately, there are no beans of type CaffeineCacheManager in app context, so it is impossible to inject it and wrap in a natural way.

Intention:

// now it fails with NoSuchBeanDefinitionException

@Configuration
class CacheConfig1 {

  @Bean
  CacheManager cacheManager(CaffeineCacheManager caffeineCacheManager) {
    return new WrappingCacheManager(caffeineCacheManager);
  }
}

Currently used variant:

@Configuration
class CacheConfig2 {

  @Bean
  CacheManager cacheManager() {

    var cfg = Caffeine.newBuilder().expireAfterWrite(60, TimeUnit.SECONDS).maximumSize(500);

    CaffeineCacheManager caffeineCacheManager = new CaffeineCacheManager();
    caffeineCacheManager.setCaffeine(cfg);

    return new WrappingCacheManager(caffeineCacheManager);
  }
}

Fragment of dependencies in pom.xml

<parent>
  <groupId>org.springframework.boot</groupId>
  <artifactId>spring-boot-starter-parent</artifactId>
  <version>2.2.7.RELEASE</version>
</parent>

...

<dependency>
  <groupId>org.springframework.boot</groupId>
  <artifactId>spring-boot-starter-cache</artifactId>
</dependency>
<dependency>
  <groupId>com.github.ben-manes.caffeine</groupId>
  <artifactId>caffeine</artifactId>
</dependency>

How to inject CaffeineCacheManager into a bean creation method and be able to create a wrapper CacheManager around it?


Solution

  • I did not find a way to inject CaffeineCacheManager, but at least it is possible to create Caffeine config from a string with Caffeine.from function. So injection of the property via @Value is a satisfactory solution.

    @Bean
    public CacheManager cacheManager(
      @Value("${spring.cache.caffeine.spec}") String caffeineSpec
    ) {
    
      var cfg = Caffeine.from(caffeineSpec);
    
      CaffeineCacheManager caffeineCacheManager = new CaffeineCacheManager();
      caffeineCacheManager.setCaffeine(cfg);
    
      return new WrappingCacheManager(caffeineCacheManager);
    }