Supported Cache Providers
The cache abstraction does not provide an actual store and relies on abstraction materialized by the org.springframework.cache.Cache
and org.springframework.cache.CacheManager
interfaces.
If you have not defined a bean of type CacheManager
or a CacheResolver
named cacheResolver
(see CachingConfigurer
), Spring Boot tries to detect the following providers (in the indicated order):
-
JCache (JSR-107) (EhCache 3, Hazelcast, Infinispan, and others)
Additionally, Spring Boot for Apache Geode provides auto-configuration for using Apache Geode as a cache provider.
It is also possible to force a particular cache provider by setting the spring.cache.type property.
Use this property if you need to disable caching altogether in certain environments (such as tests).
|
Use the spring-boot-starter-cache “Starter” to quickly add basic caching dependencies.
The starter brings in spring-context-support .
If you add dependencies manually, you must include spring-context-support in order to use the JCache or Caffeine support.
|
If the CacheManager
is auto-configured by Spring Boot, you can further tune its configuration before it is fully initialized by exposing a bean that implements the CacheManagerCustomizer
interface.
The following example sets a flag to say that null
values should not be passed down to the underlying map:
-
Java
-
Kotlin
import org.springframework.boot.autoconfigure.cache.CacheManagerCustomizer;
import org.springframework.cache.concurrent.ConcurrentMapCacheManager;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration(proxyBeanMethods = false)
public class MyCacheManagerConfiguration {
@Bean
public CacheManagerCustomizer<ConcurrentMapCacheManager> cacheManagerCustomizer() {
return (cacheManager) -> cacheManager.setAllowNullValues(false);
}
}
import org.springframework.boot.autoconfigure.cache.CacheManagerCustomizer
import org.springframework.cache.concurrent.ConcurrentMapCacheManager
import org.springframework.context.annotation.Bean
import org.springframework.context.annotation.Configuration
@Configuration(proxyBeanMethods = false)
class MyCacheManagerConfiguration {
@Bean
fun cacheManagerCustomizer(): CacheManagerCustomizer<ConcurrentMapCacheManager> {
return CacheManagerCustomizer { cacheManager ->
cacheManager.isAllowNullValues = false
}
}
}
In the preceding example, an auto-configured ConcurrentMapCacheManager is expected.
If that is not the case (either you provided your own config or a different cache provider was auto-configured), the customizer is not invoked at all.
You can have as many customizers as you want, and you can also order them by using @Order or Ordered .
|
Generic
Generic caching is used if the context defines at least one org.springframework.cache.Cache
bean.
A CacheManager
wrapping all beans of that type is created.
JCache (JSR-107)
JCache is bootstrapped through the presence of a javax.cache.spi.CachingProvider
on the classpath (that is, a JSR-107 compliant caching library exists on the classpath), and the JCacheCacheManager
is provided by the spring-boot-starter-cache
“Starter”.
Various compliant libraries are available, and Spring Boot provides dependency management for Ehcache 3, Hazelcast, and Infinispan.
Any other compliant library can be added as well.
It might happen that more than one provider is present, in which case the provider must be explicitly specified. Even if the JSR-107 standard does not enforce a standardized way to define the location of the configuration file, Spring Boot does its best to accommodate setting a cache with implementation details, as shown in the following example:
-
Properties
-
YAML
spring.cache.jcache.provider=com.example.MyCachingProvider
spring.cache.jcache.config=classpath:example.xml
# Only necessary if more than one provider is present
spring:
cache:
jcache:
provider: "com.example.MyCachingProvider"
config: "classpath:example.xml"
When a cache library offers both a native implementation and JSR-107 support, Spring Boot prefers the JSR-107 support, so that the same features are available if you switch to a different JSR-107 implementation. |
Spring Boot has general support for Hazelcast.
If a single HazelcastInstance is available, it is automatically reused for the CacheManager as well, unless the spring.cache.jcache.config property is specified.
|
There are two ways to customize the underlying javax.cache.cacheManager
:
-
Caches can be created on startup by setting the
spring.cache.cache-names
property. If a customjavax.cache.configuration.Configuration
bean is defined, it is used to customize them. -
org.springframework.boot.autoconfigure.cache.JCacheManagerCustomizer
beans are invoked with the reference of theCacheManager
for full customization.
If a standard javax.cache.CacheManager bean is defined, it is wrapped automatically in an org.springframework.cache.CacheManager implementation that the abstraction expects.
No further customization is applied to it.
|
Hazelcast
Spring Boot has general support for Hazelcast.
If a HazelcastInstance
has been auto-configured and com.hazelcast:hazelcast-spring
is on the classpath, it is automatically wrapped in a CacheManager
.
Hazelcast can be used as a JCache compliant cache or as a Spring CacheManager compliant cache.
When setting spring.cache.type to hazelcast , Spring Boot will use the CacheManager based implementation.
If you want to use Hazelcast as a JCache compliant cache, set spring.cache.type to jcache .
If you have multiple JCache compliant cache providers and want to force the use of Hazelcast, you have to explicitly set the JCache provider.
|
Infinispan
Infinispan has no default configuration file location, so it must be specified explicitly. Otherwise, the default bootstrap is used.
-
Properties
-
YAML
spring.cache.infinispan.config=infinispan.xml
spring:
cache:
infinispan:
config: "infinispan.xml"
Caches can be created on startup by setting the spring.cache.cache-names
property.
If a custom ConfigurationBuilder
bean is defined, it is used to customize the caches.
To be compatible with Spring Boot’s Jakarta EE 9 baseline, Infinispan’s -jakarta
modules must be used.
For every module with a -jakarta
variant, the variant must be used in place of the standard module.
For example, infinispan-core-jakarta
and infinispan-commons-jakarta
must be used in place of infinispan-core
and infinispan-commons
respectively.
Couchbase
If Spring Data Couchbase is available and Couchbase is configured, a CouchbaseCacheManager
is auto-configured.
It is possible to create additional caches on startup by setting the spring.cache.cache-names
property and cache defaults can be configured by using spring.cache.couchbase.*
properties.
For instance, the following configuration creates cache1
and cache2
caches with an entry expiration of 10 minutes:
-
Properties
-
YAML
spring.cache.cache-names=cache1,cache2
spring.cache.couchbase.expiration=10m
spring:
cache:
cache-names: "cache1,cache2"
couchbase:
expiration: "10m"
If you need more control over the configuration, consider registering a CouchbaseCacheManagerBuilderCustomizer
bean.
The following example shows a customizer that configures a specific entry expiration for cache1
and cache2
:
-
Java
-
Kotlin
import java.time.Duration;
import org.springframework.boot.autoconfigure.cache.CouchbaseCacheManagerBuilderCustomizer;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.couchbase.cache.CouchbaseCacheConfiguration;
@Configuration(proxyBeanMethods = false)
public class MyCouchbaseCacheManagerConfiguration {
@Bean
public CouchbaseCacheManagerBuilderCustomizer myCouchbaseCacheManagerBuilderCustomizer() {
return (builder) -> builder
.withCacheConfiguration("cache1", CouchbaseCacheConfiguration
.defaultCacheConfig().entryExpiry(Duration.ofSeconds(10)))
.withCacheConfiguration("cache2", CouchbaseCacheConfiguration
.defaultCacheConfig().entryExpiry(Duration.ofMinutes(1)));
}
}
import org.springframework.boot.autoconfigure.cache.CouchbaseCacheManagerBuilderCustomizer
import org.springframework.context.annotation.Bean
import org.springframework.context.annotation.Configuration
import org.springframework.data.couchbase.cache.CouchbaseCacheConfiguration
import java.time.Duration
@Configuration(proxyBeanMethods = false)
class MyCouchbaseCacheManagerConfiguration {
@Bean
fun myCouchbaseCacheManagerBuilderCustomizer(): CouchbaseCacheManagerBuilderCustomizer {
return CouchbaseCacheManagerBuilderCustomizer { builder ->
builder
.withCacheConfiguration(
"cache1", CouchbaseCacheConfiguration
.defaultCacheConfig().entryExpiry(Duration.ofSeconds(10))
)
.withCacheConfiguration(
"cache2", CouchbaseCacheConfiguration
.defaultCacheConfig().entryExpiry(Duration.ofMinutes(1))
)
}
}
}
Redis
If Redis is available and configured, a RedisCacheManager
is auto-configured.
It is possible to create additional caches on startup by setting the spring.cache.cache-names
property and cache defaults can be configured by using spring.cache.redis.*
properties.
For instance, the following configuration creates cache1
and cache2
caches with a time to live of 10 minutes:
-
Properties
-
YAML
spring.cache.cache-names=cache1,cache2
spring.cache.redis.time-to-live=10m
spring:
cache:
cache-names: "cache1,cache2"
redis:
time-to-live: "10m"
By default, a key prefix is added so that, if two separate caches use the same key, Redis does not have overlapping keys and cannot return invalid values.
We strongly recommend keeping this setting enabled if you create your own RedisCacheManager .
|
You can take full control of the default configuration by adding a RedisCacheConfiguration @Bean of your own.
This can be useful if you need to customize the default serialization strategy.
|
If you need more control over the configuration, consider registering a RedisCacheManagerBuilderCustomizer
bean.
The following example shows a customizer that configures a specific time to live for cache1
and cache2
:
-
Java
-
Kotlin
import java.time.Duration;
import org.springframework.boot.autoconfigure.cache.RedisCacheManagerBuilderCustomizer;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.cache.RedisCacheConfiguration;
@Configuration(proxyBeanMethods = false)
public class MyRedisCacheManagerConfiguration {
@Bean
public RedisCacheManagerBuilderCustomizer myRedisCacheManagerBuilderCustomizer() {
return (builder) -> builder
.withCacheConfiguration("cache1", RedisCacheConfiguration
.defaultCacheConfig().entryTtl(Duration.ofSeconds(10)))
.withCacheConfiguration("cache2", RedisCacheConfiguration
.defaultCacheConfig().entryTtl(Duration.ofMinutes(1)));
}
}
import org.springframework.boot.autoconfigure.cache.RedisCacheManagerBuilderCustomizer
import org.springframework.context.annotation.Bean
import org.springframework.context.annotation.Configuration
import org.springframework.data.redis.cache.RedisCacheConfiguration
import java.time.Duration
@Configuration(proxyBeanMethods = false)
class MyRedisCacheManagerConfiguration {
@Bean
fun myRedisCacheManagerBuilderCustomizer(): RedisCacheManagerBuilderCustomizer {
return RedisCacheManagerBuilderCustomizer { builder ->
builder
.withCacheConfiguration(
"cache1", RedisCacheConfiguration
.defaultCacheConfig().entryTtl(Duration.ofSeconds(10))
)
.withCacheConfiguration(
"cache2", RedisCacheConfiguration
.defaultCacheConfig().entryTtl(Duration.ofMinutes(1))
)
}
}
}
Caffeine
Caffeine is a Java 8 rewrite of Guava’s cache that supersedes support for Guava.
If Caffeine is present, a CaffeineCacheManager
(provided by the spring-boot-starter-cache
“Starter”) is auto-configured.
Caches can be created on startup by setting the spring.cache.cache-names
property and can be customized by one of the following (in the indicated order):
-
A cache spec defined by
spring.cache.caffeine.spec
-
A
com.github.benmanes.caffeine.cache.CaffeineSpec
bean is defined -
A
com.github.benmanes.caffeine.cache.Caffeine
bean is defined
For instance, the following configuration creates cache1
and cache2
caches with a maximum size of 500 and a time to live of 10 minutes
-
Properties
-
YAML
spring.cache.cache-names=cache1,cache2
spring.cache.caffeine.spec=maximumSize=500,expireAfterAccess=600s
spring:
cache:
cache-names: "cache1,cache2"
caffeine:
spec: "maximumSize=500,expireAfterAccess=600s"
If a com.github.benmanes.caffeine.cache.CacheLoader
bean is defined, it is automatically associated to the CaffeineCacheManager
.
Since the CacheLoader
is going to be associated with all caches managed by the cache manager, it must be defined as CacheLoader<Object, Object>
.
The auto-configuration ignores any other generic type.
Cache2k
Cache2k is an in-memory cache.
If the Cache2k spring integration is present, a SpringCache2kCacheManager
is auto-configured.
Caches can be created on startup by setting the spring.cache.cache-names
property.
Cache defaults can be customized using a Cache2kBuilderCustomizer
bean.
The following example shows a customizer that configures the capacity of the cache to 200 entries, with an expiration of 5 minutes:
-
Java
-
Kotlin
import java.util.concurrent.TimeUnit;
import org.springframework.boot.autoconfigure.cache.Cache2kBuilderCustomizer;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration(proxyBeanMethods = false)
public class MyCache2kDefaultsConfiguration {
@Bean
public Cache2kBuilderCustomizer myCache2kDefaultsCustomizer() {
return (builder) -> builder.entryCapacity(200)
.expireAfterWrite(5, TimeUnit.MINUTES);
}
}
import org.springframework.boot.autoconfigure.cache.Cache2kBuilderCustomizer
import org.springframework.context.annotation.Bean
import org.springframework.context.annotation.Configuration
import java.util.concurrent.TimeUnit
@Configuration(proxyBeanMethods = false)
class MyCache2kDefaultsConfiguration {
@Bean
fun myCache2kDefaultsCustomizer(): Cache2kBuilderCustomizer {
return Cache2kBuilderCustomizer { builder ->
builder.entryCapacity(200)
.expireAfterWrite(5, TimeUnit.MINUTES)
}
}
}
Simple
If none of the other providers can be found, a simple implementation using a ConcurrentHashMap
as the cache store is configured.
This is the default if no caching library is present in your application.
By default, caches are created as needed, but you can restrict the list of available caches by setting the cache-names
property.
For instance, if you want only cache1
and cache2
caches, set the cache-names
property as follows:
-
Properties
-
YAML
spring.cache.cache-names=cache1,cache2
spring:
cache:
cache-names: "cache1,cache2"
If you do so and your application uses a cache not listed, then it fails at runtime when the cache is needed, but not on startup. This is similar to the way the "real" cache providers behave if you use an undeclared cache.
None
When @EnableCaching
is present in your configuration, a suitable cache configuration is expected as well.
If you need to disable caching altogether in certain environments, force the cache type to none
to use a no-op implementation, as shown in the following example:
-
Properties
-
YAML
spring.cache.type=none
spring:
cache:
type: "none"