> For the complete documentation index, see [llms.txt](https://potoyang.gitbook.io/spring-in-action-v4/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://potoyang.gitbook.io/spring-in-action-v4/untitled-7/untitled-3.md).

# 13.1　启用对缓存的支持

Spring 对缓存的支持有两种方式：

* 注解驱动的缓存
* XML 声明的缓存

使用 Spring 的缓存抽象时，最为通用的方式就是在方法上添加 @Cacheable 和 @CacheEvict 注解。在本章中，大多数内容都会使用这种类型的声明式注解。在 13.3 小节中，我们会看到如何使用 XML 来声明缓存边界。

在往 bean 上添加缓存注解之前，必须要启用 Spring 对注解驱动缓存的支持。如果我们使用 Java 配置的话，那么可以在其中的一个配置类上添加 @EnableCaching，这样的话就能启用注解驱动的缓存。程序清单 13.1 展现了如何实际使用 @EnableCaching。

{% code title="程序清单 13.1　通过使用 @EnableCaching 启用注解驱动的缓存" %}

```java
package spittr.config;

import net.sf.ehcache.CacheManager;

import org.springframework.cache.annotation.EnableCaching;
import org.springframework.cache.ehcache.EhCacheCacheManager;
import org.springframework.cache.ehcache.EhCacheManagerFactoryBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.io.ClassPathResource;

@Configuration
@EnableCaching
public class CachingConfig {

  @Bean
  public EhCacheCacheManager cacheManager(CacheManager cm) {
    return new EhCacheCacheManager(cm);
  }

}
```

{% endcode %}

程序清单 13.1 通过使用 @EnableCaching 启用注解驱动的缓存如果以 XML 的方式配置应用的话，那么可以使用 Spring cache 命名空间中的 \<cache:annotation-driven> 元素来启用注解驱动的缓存。

{% code title="程序清单 13.2　通过使用启用注解驱动的缓存" %}

```markup
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xmlns:cache="http://www.springframework.org/schema/cache"
  xsi:schemaLocation="
    http://www.springframework.org/schema/beans 
    http://www.springframework.org/schema/beans/spring-beans.xsd
    http://www.springframework.org/schema/cache
    http://www.springframework.org/schema/cache/spring-cache.xsd" >
  
  <cache:annotation-driven />
  
  <bean id="cacheManager" class="org.springframework.cache.concurrent.ConcurrentMapCacheManager" />

</beans>
```

{% endcode %}

其实在本质上，@EnableCaching 和 \<cache:annotation-driven> 的工作方式是相同的。它们都会创建一个切面（aspect）并触发 Spring 缓存注解的切点（pointcut）。根据所使用的注解以及缓存的状态，这个切面会从缓存中获取数据，将数据添加到缓存之中或者从缓存中移除某个值。

在程序清单 13.1 和程序清单 13.2 中，你可能已经注意到了，它们不仅仅启用了注解驱动的缓存，还声明了一个缓存管理器（cache manager）的 bean。缓存管理器是 Spring 缓存抽象的核心，它能够与多个流行的缓存实现进行集成。

在本例中，声明了 ConcurrentMapCacheManager，这个简单的缓存管理器使用java.util.concurrent.ConcurrentHashMap 作为其缓存存储。它非常简单，因此对于开发、测试或基础的应用来讲，这是一个很不错的选择。但它的缓存存储是基于内存的，所以它的生命周期是与应用关联的，对于生产级别的大型企业级应用程序， 这可能并不是理想的选择。

幸好，有多个很棒的缓存管理器方案可供使用。让我们看一下几个最为常用的缓存管理器。
