deveth0
deveth0

Reputation: 508

Configuration for specific Caffeine Caches in Spring

We need to implement several methods that have different caching times. Each method is annotated with @Cacheable and our current solution includes multiple CacheManager that are set in a CachingConfigurerSupport.

public class CachingConfiguration extends CachingConfigurerSupport {

  @Override
  @Bean
  public CacheManager cacheManager() {
    CaffeineCacheManager cacheManager = new CaffeineCacheManager();
    cacheManager.setCaffeine(Caffeine.newBuilder().expireAfterWrite(1, TimeUnit.DAYS));
    return cacheManager;
  }

  @Bean
  public CacheManager anotherCache() {
    CaffeineCacheManager cacheManager = new CaffeineCacheManager();
    cacheManager.setCaffeine(Caffeine.newBuilder().expireAfterWrite(1, TimeUnit.MINUTES));
    return cacheManager;
  }
}

The @Cacheable annotation then included the cacheManager: @Cacheable(cacheNames = "someCache", cacheManager = "anotherCache")

Basically that's fine but is also errorprune if you forget the cacheManager parameter etc.

So I currently try to find a better solution but as far as I can see, there is currently no general accepted way to go.

Imho the main advantage of the CaffeineCacheManager compared to e.g. SimpleCacheManager is the possibility to define a base configuration and then initialize additional caches lazily. But wouldn't it be great if you are able to set additional caches which are never reinitialized?

Those caches must be used preferentially and created in the CachingConfigurerSupport.

Maybe I'm missing something, but shouldn't this solve the problem that has already been discussed in several threads in different forms?

Upvotes: 4

Views: 8144

Answers (2)

Vladimir Konkov
Vladimir Konkov

Reputation: 162

Simple way without any thrid-party lib:

spring.cache.type=caffeine
# default spec (optional)
spring.cache.caffeine.spec=maximumSize=250,expireAfterWrite=15m
# specific specs (also optional)
caffeine.specs.places=maximumSize=1000,expireAfterWrite=1h

Register custom caches:

applicationContext.registerBean { context ->
    CacheManagerCustomizer<CaffeineCacheManager> { cacheManager ->
        for (spec in Binder.get(context.environment).bindOrCreate("caffeine.specs", HashMap::class.java)) {
            cacheManager.registerCustomCache(spec.key.toString(), Caffeine.from(spec.value.toString()).build())
        }
    }
}

Upvotes: 0

stepio
stepio

Reputation: 905

Recently I decided to turn my initial PR into a separate tiny project.

To start using it just add the latest dependency from Maven Central:

<dependency>
    <groupId>io.github.stepio.coffee-boots</groupId>
    <artifactId>coffee-boots</artifactId>
    <version>2.0.0</version>
</dependency>

Format of properties is the following:

coffee-boots.cache.spec.myCache=maximumSize=100000,expireAfterWrite=1m

If no specific configuration is defined, CacheManager defaults to Spring's behavior.

Upvotes: 2

Related Questions