[[cache-store-configuration]]
= Configuring the Cache Storage

The cache abstraction provides several storage integration options. To use them, you need
to declare an appropriate `CacheManager` (an entity that controls and manages `Cache`
instances and that can be used to retrieve these for storage).


[[cache-store-configuration-jdk]]
== JDK `ConcurrentMap`-based Cache

The JDK-based `Cache` implementation resides under
`org.springframework.cache.concurrent` package. It lets you use `ConcurrentHashMap`
as a backing `Cache` store. The following example shows how to configure two caches:

include-code::./CacheConfiguration[tag=snippet,indent=0]

The preceding snippet uses the `SimpleCacheManager` to create a `CacheManager` for the
two nested `ConcurrentMapCache` instances named `default` and `books`. Note that the
names are configured directly for each cache.

As the cache is created by the application, it is bound to its lifecycle, making it
suitable for basic use cases, tests, or simple applications. The cache scales well
and is very fast, but it does not provide any management, persistence capabilities,
or eviction contracts.


[[cache-store-configuration-eviction]]
== Ehcache-based Cache

Ehcache 3.x is fully JSR-107 compliant and no dedicated support is required for it. See
xref:integration/cache/store-configuration.adoc#cache-store-configuration-jsr107[JSR-107 Cache] for details.


[[cache-store-configuration-caffeine]]
== Caffeine Cache

Caffeine is a Java 8 rewrite of Guava's cache, and its implementation is located in the
`org.springframework.cache.caffeine` package and provides access to several features
of Caffeine.

The following example configures a `CacheManager` that creates the cache on demand:

include-code::./CacheConfiguration[tag=snippet,indent=0]

You can also provide the caches to use explicitly. In that case, only those
are made available by the manager. The following example shows how to do so:

include-code::./CustomCacheConfiguration[tag=snippet,indent=0]

The Caffeine `CacheManager` also supports custom `Caffeine` and `CacheLoader`.
See the https://github.com/ben-manes/caffeine/wiki[Caffeine documentation]
for more information about those.


[[cache-store-configuration-gemfire]]
== GemFire-based Cache

GemFire is a memory-oriented, disk-backed, elastically scalable, continuously available,
active (with built-in pattern-based subscription notifications), globally replicated
database and provides fully-featured edge caching. For further information on how to
use GemFire as a `CacheManager` (and more), see the
{docs-spring-gemfire}/html/[Spring Data GemFire reference documentation].


[[cache-store-configuration-jsr107]]
== JSR-107 Cache

Spring's caching abstraction can also use JSR-107-compliant caches. The JCache
implementation is located in the `org.springframework.cache.jcache` package.

Again, to use it, you need to declare the appropriate `CacheManager`.
The following example shows how to do so:

include-code::./CacheConfiguration[tag=snippet,indent=0]


[[cache-store-configuration-noop]]
== Dealing with Caches without a Backing Store

Sometimes, when switching environments or doing testing, you might have cache
declarations without having an actual backing cache configured. As this is an invalid
configuration, an exception is thrown at runtime, since the caching infrastructure
is unable to find a suitable store. In situations like this, rather than removing the
cache declarations (which can prove tedious), you can wire in a simple dummy cache that
performs no caching -- that is, it forces the cached methods to be invoked every time.
The following example shows how to do so:

include-code::./CacheConfiguration[tag=snippet,indent=0]

The `CompositeCacheManager` in the preceding chains multiple `CacheManager` instances and,
through the `fallbackToNoOpCache` flag, adds a no-op cache for all the definitions not
handled by the configured cache managers. That is, every cache definition not found in
either `jdkCache` or `gemfireCache` (configured earlier in the example) is handled by
the no-op cache, which does not store any information, causing the target method to be
invoked every time.
