***
The Spring Framework provides support for transparently adding caching to an existing Spring application. Similar to the [transaction](https://docs.spring.io/spring-framework/docs/current/reference/html/data-access.html#transaction) support, the caching abstraction allows consistent use of various caching solutions with minimal impact on the code.
In Spring Framework 4.1, the cache abstraction was significantly extended with support for [JSR-107 annotations](https://docs.spring.io/spring-framework/docs/current/reference/html/integration.html#cache-jsr-107) and more customization options.
>The Spring abstraction layer lets us use a cache independently of the cache provider.
### How to add Spring Cache Abstraction dependency?
The core caching abstraction provided by Spring resides in the _[spring-context](https://search.maven.org/search?q=g:org.springframework%20a:spring-context)_ module. So when using Maven, our _pom.xml_ should contain it.
> [!NOTE]
> Interestingly, there is another module named _[spring-context-support](https://search.maven.org/search?q=g:org.springframework%20a:spring-context-support),_ which sits on top of the _spring-context_ module and provides a few more _CacheManagers_ backed by the likes of [EhCache](https://www.baeldung.com/spring-boot-ehcache) or [Caffeine](https://www.baeldung.com/java-caching-caffeine). If we want to use those as our cache storage, then we need to use the _spring-context-support_ module instead:
If we use Spring Boot, then we can utilize the _[spring-boot-starter-cache](https://search.maven.org/search?q=g:org.springframework.boot%20a:spring-boot-starter-cache)_ starter package to easily add the caching dependencies:
```xml
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-cache</artifactId>
<version>3.2.1</version>
</dependency>
```
This starter provides all classes we need to support the cache. These are mainly the interfaces `Cache` and `CacheManager` that should be implemented by the provider, and the annotations for the methods and classes that we can use to mark methods as cacheable.
> [!NOTE] Cache Providers
> Spring Boot supports several cache [providers](https://docs.spring.io/spring-boot/docs/current/reference/htmlsingle/#boot-features-caching-provider). If Spring Boot finds a cache provider on the classpath, it tries to find a default configuration for this provider. If it doesn’t find a provider, it configures the `Simple` provider, which is just a `ConcurrentHashMap`.
### How to enable Spring Cache Abstraction?
To enable caching, Spring makes good use of annotations, much like enabling any other configuration level feature in the framework.
We can enable the caching feature simply by adding the _@EnableCaching_ annotation to any of the configuration classes:
```java
@Configuration
@EnableCaching
class EmbeddedCacheConfig {
// Other methods omitted.
}
```
The annotation `@EnableCaching` will start the search for a `CacheManger` bean to configure the cache provider. After enabling the cache, we are ready to use it. But we didn’t define any cache provider, so as mentioned above, a `Simple` in-memory provider would be used. This simple cache might be good for testing, but we want to [[Spring - How to setup Caffeine cache provider| use a "real" cache in production]].
Also, we can customize the [auto-configured](https://github.com/spring-projects/spring-boot/blob/master/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/cache/CacheAutoConfiguration.java) _CacheManager_ using one or more `CacheManagerCustomizer<T>` beans:
```java
@Component
public class SimpleCacheCustomizer
implements CacheManagerCustomizer<ConcurrentMapCacheManager> {
@Override
public void customize(ConcurrentMapCacheManager cacheManager) {
cacheManager.setCacheNames(asList("users", "transactions"));
}
}
```
The _[CacheAutoConfiguration](https://github.com/spring-projects/spring-boot/blob/master/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/cache/CacheAutoConfiguration.java)_ auto-configuration picks up these customizers and applies them to the current _CacheManager_ before its complete initialization.
***
**References**:
- [A Guide To Caching in Spring](https://www.baeldung.com/spring-cache-tutorial)
- [Implementing a Cache with Spring Boot](https://reflectoring.io/spring-boot-cache/)
- [Spring Boot OI](https://docs.spring.io/spring-boot/docs/current/reference/html/io.html#io.caching)