The Spring Framework provides support for transparently adding caching to an application. At its core, the abstraction applies caching to methods, reducing thus the number of executions based on the information available in the cache. The caching logic is applied transparently, without any interference to the invoker.

[Note] Note

Check the relevant section of the Spring Framework reference for more details.

In a nutshell, adding caching to an operation of your service is as easy as adding the relevant annotation to its method:

import javax.cache.annotation.CacheResult;
import org.springframework.stereotype.Component;
@Component
public class MathService {
    @CacheResult
    public int computePiDecimal(int i) {
        // ...
}
[Note] Note

You can either use the standard JSR-107 (JCache) annotations or Spring’s own caching annotations transparently. We strongly advise you however to not mix and match them.

[Tip] Tip

It is also possible to update or evict data from the cache transparently.

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. Spring Boot auto-configures a suitable CacheManager according to the implementation as long as the caching support is enabled via the @EnableCaching annotation.

[Note] Note

If you are using the cache infrastructure with beans that are not interface-based, make sure to enable the proxyTargetClass attribute of @EnableCaching .

[Tip] Tip

Use the spring-boot-starter-cache ‘Starter’ to quickly add basic caching dependencies. The starter brings spring-context-support : if you are adding dependencies manually, you must include it if you intend to use the JCache, EhCache 2.x or Guava support.

If you haven’t defined a bean of type CacheManager or a CacheResolver named cacheResolver (see CachingConfigurer ), Spring Boot tries to detect the following providers (in this order):

[Tip] Tip

It is also possible to force the cache provider to use via the spring.cache.type property. Use this property if you need to disable caching altogether in certain environment (e.g. tests).

If the CacheManager is auto-configured by Spring Boot, you can further tune its configuration before it is fully initialized by exposing a bean implementing the CacheManagerCustomizer interface. The following sets the cache names to use.

@Bean
public CacheManagerCustomizer<ConcurrentMapCacheManager> cacheManagerCustomizer() {
    return new CacheManagerCustomizer<ConcurrentMapCacheManager>() {
        @Override
        public void customize(ConcurrentMapCacheManager cacheManager) {
            cacheManager.setCacheNames(Arrays.asList("one", "two"));
}
[Note] Note

In the example above, a ConcurrentMapCacheManager is expected to be configured. If that is not the case, the customizer won’t be invoked at all. You can have as many customizers as you want and you can also order them as usual using @Order or Ordered .

JCache is bootstrapped via the presence of a javax.cache.spi.CachingProvider on the classpath (i.e. a JSR-107 compliant caching library) and the JCacheCacheManager provided by the spring-boot-starter-cache ‘Starter’. There are various compliant libraries out there 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 with implementation details.

# Only necessary if more than one provider is present
spring.cache.jcache.provider=com.acme.MyCachingProvider
spring.cache.jcache.config=classpath:acme.xml
[Note] Note

Since a cache library may offer both a native implementation and JSR-107 support Spring Boot will prefer the JSR-107 support so that the same features are available if you switch to a different JSR-107 implementation.

[Tip] Tip

Spring Boot has a 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 several ways to customize the underlying javax.cache.cacheManager :

[Tip] Tip

If a standard javax.cache.CacheManager bean is defined, it is wrapped automatically in a org.springframework.cache.CacheManager implementation that the abstraction expects. No further customization is applied on it.

Spring Boot has a general support for Hazelcast . If a HazelcastInstance has been auto-configured, it is automatically wrapped in a CacheManager .

If the Couchbase java client and the couchbase-spring-cache implementation are available and Couchbase is configured , a CouchbaseCacheManager will be auto-configured. It is also possible to create additional caches on startup using the spring.cache.cache-names property. These will operate on the Bucket that was auto-configured. You can also create additional caches on another Bucket using the customizer: assume you need two caches on the "main" Bucket ( foo and bar ) and one biz cache with a custom time to live of 2sec on the another Bucket . First, you can create the two first caches simply via configuration:

spring.cache.cache-names=foo,bar

Then define this extra @Configuration to configure the extra Bucket and the biz cache:

@Configuration
public class CouchbaseCacheConfiguration {
    private final Cluster cluster;
    public CouchbaseCacheConfiguration(Cluster cluster) {
        this.cluster = cluster;
    @Bean
    public Bucket anotherBucket() {
        return this.cluster.openBucket("another", "secret");
    @Bean
    public CacheManagerCustomizer<CouchbaseCacheManager> cacheManagerCustomizer() {
        return c -> {
            c.prepareCache("biz", CacheBuilder.newInstance(anotherBucket())
                    .withExpiration(2));
}

This sample configuration reuses the Cluster that was created via auto-configuration.

If Redis is available and configured, the RedisCacheManager is auto-configured. It is also possible to create additional caches on startup using the spring.cache.cache-names property.

[Note] Note

By default, a key prefix is added to prevent that if two separate caches use the same key, Redis would have overlapping keys and be likely to return invalid values. We strongly recommend to keep this setting enabled if you create your own RedisCacheManager .