# 31. 缓存

Spring框架提供为应用透明添加缓存的支持。其核心思想是：将抽象应用到缓存方法，基于缓存中可用信息减少方法的执行。缓存逻辑的应用是透明的，不会干扰调用者。只要通过`@EnableCaching`注解开启缓存支持，Spring Boot就会自动配置缓存基础结构。

**注** 具体参考Spring框架指南的[相应章节](https://docs.spring.io/spring/docs/5.0.4.RELEASE/spring-framework-reference/integration.html#cache)。

简而言之，为服务的某个操作添加缓存跟为方法添加相应注解那样简单。如下所示：

```java
import org.springframework.cache.annotation.Cacheable
import org.springframework.stereotype.Component;

@Component
public class MathService {

    @Cacheable("piDecimals")
    public int computePiDecimal(int i) {
        // ...
    }

}
```

这个例子展示了如何缓存一个开销昂贵的操作。在调用`computePiDecimal`方法之前，抽象将会在匹配参数`i`的`piDecimals`缓存中寻找一个入口。如果找到入口，缓存中的内容会被立即返回给调用者，且方法不会被调用。否则，方法会被调用，在返回值之前，缓存会被更新。

**注** 你也可以透明地使用标准的JSR-107 (JCache)注解（比如`@CacheResult`）。我们强烈建议你不要混淆使用。

如果你不添加特定的缓存库，Spring Boot将会自动配置一个在内存中使用并发映射的[Simple提供商](https://jack80342.gitbook.io/spring-boot/iv.-spring-boot-features/31.-caching/31.1-supported-cache-providers/31.1.9-simple)。当需要缓存时（比如上面的例子里的`piDecimals`），提供商将会为你实时创建。不推荐你在产品环境中使用Simple提供商。但是它使得入门变得非常容易，确保了你理解特性。当你下定决心使用某个缓存提供商，请阅读这份文档理解如何配置缓存。实际上所有的提供商，都要求你明确地配置你在应用中使用的每一处缓存。有些提供了方法，通过`spring.cache.cache-names`来自定义默认的缓存。

**提示** 透明地[更新](https://docs.spring.io/spring/docs/5.0.4.RELEASE/spring-framework-reference/integration.html#cache-annotations-put)或[去除](https://docs.spring.io/spring/docs/5.0.4.RELEASE/spring-framework-reference/integration.html#cache-annotations-evict)缓存数据也是可以的。

**注** 如果你正在使用的缓存基础结构beans不是基于接口的，确保启用了`@EnableCaching`的`proxyTargetClass`属性。
