| 对于最新的稳定版本,请使用 Spring Boot 3.5.5! | 
缓存
Spring Framework 支持透明地向应用程序添加缓存。
从本质上讲,该抽象将缓存应用于方法,从而根据缓存中可用的信息减少执行次数。
缓存逻辑是透明应用的,不会对调用者产生任何干扰。
只要使用@EnableCaching注解。
| 查看 Spring Framework 参考的相关部分以获取更多详细信息。 | 
简而言之,要将缓存添加到服务的作中,请将相关注释添加到其方法中,如以下示例所示:
- 
Java 
- 
Kotlin 
import org.springframework.cache.annotation.Cacheable;
import org.springframework.stereotype.Component;
@Component
public class MyMathService {
	@Cacheable("piDecimals")
	public int computePiDecimal(int precision) {
		...
	}
}import org.springframework.cache.annotation.Cacheable
import org.springframework.stereotype.Component
@Component
class MyMathService {
	@Cacheable("piDecimals")
	fun computePiDecimal(precision: Int): Int {
		...
	}
}此示例演示了在可能代价高昂的作上使用缓存。
调用之前computePiDecimal,抽象会在piDecimals缓存,与precision论点。
如果找到条目,则缓存中的内容将立即返回给调用方,并且不会调用该方法。
否则,将调用该方法,并在返回值之前更新缓存。
| 您还可以使用标准 JSR-107 (JCache) 注释(例如 @CacheResult) 透明。
但是,我们强烈建议您不要混合和匹配 Spring Cache 和 JCache 注释。 | 
如果您不添加任何特定的缓存库,Spring Boot 会自动配置一个在内存中使用并发映射的简单提供程序。
当需要缓存时(例如piDecimals在前面的示例中),此提供程序会为您创建它。
不建议将简单的提供程序用于生产使用,但它非常适合入门并确保您了解这些功能。
当您决定要使用的缓存提供程序时,请务必阅读其文档以了解如何配置应用程序使用的缓存。
几乎所有提供程序都要求显式配置在应用程序中使用的每个缓存。
有些提供了一种自定义默认缓存的方法,由spring.cache.cache-names财产。
支持的缓存提供程序
缓存抽象不提供实际的存储,而是依赖于Cache和CacheManager接口。
如果您尚未定义类型为CacheManager或CacheResolver叫cacheResolver(参见CachingConfigurer),Spring Boot 尝试检测以下提供程序(按指示的顺序):
| 如果 CacheManager由 Spring Boot 自动配置,可以通过设置spring.cache.type财产。
如果您需要在某些环境(例如测试)中使用无作缓存,请使用此属性。 | 
| 使用 spring-boot-starter-cacheStarter 快速添加基本缓存依赖项。
首发带入spring-context-support.
如果手动添加依赖项,则必须包含spring-context-support以便使用 JCache 或 Caffeine 支持。 | 
如果CacheManager由 Spring Boot 自动配置,您可以通过公开实现CacheManagerCustomizer接口。
以下示例设置了一个标志来说明null不应将值向下传递给底层映射:
- 
Java 
- 
Kotlin 
import org.springframework.boot.autoconfigure.cache.CacheManagerCustomizer;
import org.springframework.cache.concurrent.ConcurrentMapCacheManager;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration(proxyBeanMethods = false)
public class MyCacheManagerConfiguration {
	@Bean
	public CacheManagerCustomizer<ConcurrentMapCacheManager> cacheManagerCustomizer() {
		return (cacheManager) -> cacheManager.setAllowNullValues(false);
	}
}import org.springframework.boot.autoconfigure.cache.CacheManagerCustomizer
import org.springframework.cache.concurrent.ConcurrentMapCacheManager
import org.springframework.context.annotation.Bean
import org.springframework.context.annotation.Configuration
@Configuration(proxyBeanMethods = false)
class MyCacheManagerConfiguration {
	@Bean
	fun cacheManagerCustomizer(): CacheManagerCustomizer<ConcurrentMapCacheManager> {
		return CacheManagerCustomizer { cacheManager ->
			cacheManager.isAllowNullValues = false
		}
	}
}| 在前面的示例中,自动配置的 ConcurrentMapCacheManager是意料之中的。
如果不是这种情况(您提供了自己的配置或自动配置了不同的缓存提供程序),则根本不会调用定制器。
您可以根据需要拥有任意数量的定制器,也可以使用@Order或Ordered. | 
通用
如果上下文定义了至少一个Cache豆。
一个CacheManager包装该类型的所有 bean。
JCache (JSR-107)
JCache 是通过存在CachingProvider在类路径上(即,类路径上存在一个符合 JSR-107 的缓存库),并且JCacheCacheManager由spring-boot-starter-cache起动机。
有各种兼容库可用,Spring Boot 为 Ehcache 3、Hazelcast 和 Infinispan 提供依赖管理。
也可以添加任何其他兼容库。
可能会出现多个提供程序,在这种情况下,必须显式指定提供程序。 即使 JSR-107 标准没有强制执行标准化方法来定义配置文件的位置,Spring Boot 也会尽最大努力适应使用实现详细信息设置缓存,如以下示例所示:
- 
Properties 
- 
YAML 
spring.cache.jcache.provider=com.example.MyCachingProvider
spring.cache.jcache.config=classpath:example.xml# Only necessary if more than one provider is present
spring:
  cache:
    jcache:
      provider: "com.example.MyCachingProvider"
      config: "classpath:example.xml"| 当缓存库同时提供本机实现和 JSR-107 支持时,Spring Boot 更喜欢 JSR-107 支持,因此当您切换到不同的 JSR-107 实现时,可以使用相同的功能。 | 
| Spring Boot 对 Hazelcast 有一般支持。
如果单个 HazelcastInstance可用时,它会自动重用于CacheManager同样,除非spring.cache.jcache.config属性。 | 
有两种方法可以自定义底层CacheManager:
- 
可以通过在启动时创建缓存,方法是将 spring.cache.cache-names财产。 如果自定义Configurationbean 被定义,它用于自定义它们。
- 
JCacheManagerCustomizerbean 使用CacheManager用于完全定制。
| 如果标准 CacheManagerbean 时,它会自动包装在CacheManager抽象期望的实现。不会对其应用进一步的自定义。 | 
榛铸
Spring Boot 对 Hazelcast 有一般支持。如果HazelcastInstance已自动配置,并且com.hazelcast:hazelcast-spring在类路径上,它会自动包装在CacheManager.
| Hazelcast 可以用作符合 JCache 的缓存或 Spring CacheManagercompliant cache。设置spring.cache.type自hazelcast,Spring Boot 将使用CacheManager基于实现。如果要将 Hazelcast 用作符合 JCache 的缓存,请将spring.cache.type自jcache. 如果您有多个符合 JCache 的缓存提供程序并希望强制使用 Hazelcast,则必须显式设置 JCache 提供程序。 | 
无限跨度
Infinispan 没有默认配置文件位置,因此必须显式指定。否则,使用默认引导程序。
- 
Properties 
- 
YAML 
spring.cache.infinispan.config=infinispan.xmlspring:
  cache:
    infinispan:
      config: "infinispan.xml"可以通过在启动时创建缓存,方法是将spring.cache.cache-names财产。
如果自定义ConfigurationBuilderbean 定义,它用于自定义缓存。
为了与 Spring Boot 的 Jakarta EE 9 基线兼容,Infinispan 的-jakarta模块。对于每个具有-jakartavariant,则必须使用该变型来代替标准模块。 例如infinispan-core-jakarta和infinispan-commons-jakarta必须用来代替infinispan-core和infinispan-commons分别。
沙发底座
如果 Spring Data Couchbase 可用并且配置了 Couchbase,则CouchbaseCacheManager是自动配置的。可以通过设置spring.cache.cache-names属性和缓存默认值可以通过使用spring.cache.couchbase.*性能。 例如,以下配置会创建cache1和cache2条目过期时间为 10 分钟的缓存:
- 
Properties 
- 
YAML 
spring.cache.cache-names=cache1,cache2
spring.cache.couchbase.expiration=10mspring:
  cache:
    cache-names: "cache1,cache2"
    couchbase:
      expiration: "10m"如果您需要对配置进行更多控制,请考虑注册CouchbaseCacheManagerBuilderCustomizer豆。 以下示例显示了一个定制器,该定制器为cache1和cache2:
- 
Java 
- 
Kotlin 
import java.time.Duration;
import org.springframework.boot.autoconfigure.cache.CouchbaseCacheManagerBuilderCustomizer;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.couchbase.cache.CouchbaseCacheConfiguration;
@Configuration(proxyBeanMethods = false)
public class MyCouchbaseCacheManagerConfiguration {
	@Bean
	public CouchbaseCacheManagerBuilderCustomizer myCouchbaseCacheManagerBuilderCustomizer() {
		return (builder) -> builder
				.withCacheConfiguration("cache1", CouchbaseCacheConfiguration
						.defaultCacheConfig().entryExpiry(Duration.ofSeconds(10)))
				.withCacheConfiguration("cache2", CouchbaseCacheConfiguration
						.defaultCacheConfig().entryExpiry(Duration.ofMinutes(1)));
	}
}import org.springframework.boot.autoconfigure.cache.CouchbaseCacheManagerBuilderCustomizer
import org.springframework.context.annotation.Bean
import org.springframework.context.annotation.Configuration
import org.springframework.data.couchbase.cache.CouchbaseCacheConfiguration
import java.time.Duration
@Configuration(proxyBeanMethods = false)
class MyCouchbaseCacheManagerConfiguration {
	@Bean
	fun myCouchbaseCacheManagerBuilderCustomizer(): CouchbaseCacheManagerBuilderCustomizer {
		return CouchbaseCacheManagerBuilderCustomizer { builder ->
			builder
				.withCacheConfiguration(
					"cache1", CouchbaseCacheConfiguration
						.defaultCacheConfig().entryExpiry(Duration.ofSeconds(10))
				)
				.withCacheConfiguration(
					"cache2", CouchbaseCacheConfiguration
						.defaultCacheConfig().entryExpiry(Duration.ofMinutes(1))
				)
		}
	}
}Redis
如果 Redis 可用并已配置,则RedisCacheManager是自动配置的。可以通过设置spring.cache.cache-names属性和缓存默认值可以通过使用spring.cache.redis.*性能。 例如,以下配置会创建cache1和cache2生存时间为 10 分钟的缓存:
- 
Properties 
- 
YAML 
spring.cache.cache-names=cache1,cache2
spring.cache.redis.time-to-live=10mspring:
  cache:
    cache-names: "cache1,cache2"
    redis:
      time-to-live: "10m"| 默认情况下,会添加键前缀,以便如果两个单独的缓存使用相同的键,Redis 不会有重叠的键,并且不会返回无效值。如果您创建自己的设置,我们强烈建议您保持启用此设置 RedisCacheManager. | 
| 您可以通过添加 RedisCacheConfiguration@Bean您自己的。如果您需要自定义默认序列化策略,这会很有用。 | 
如果您需要对配置进行更多控制,请考虑注册RedisCacheManagerBuilderCustomizer豆。 以下示例显示了一个定制器,该定制器配置了特定的生存时间cache1和cache2:
- 
Java 
- 
Kotlin 
import java.time.Duration;
import org.springframework.boot.autoconfigure.cache.RedisCacheManagerBuilderCustomizer;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.cache.RedisCacheConfiguration;
@Configuration(proxyBeanMethods = false)
public class MyRedisCacheManagerConfiguration {
	@Bean
	public RedisCacheManagerBuilderCustomizer myRedisCacheManagerBuilderCustomizer() {
		return (builder) -> builder
				.withCacheConfiguration("cache1", RedisCacheConfiguration
						.defaultCacheConfig().entryTtl(Duration.ofSeconds(10)))
				.withCacheConfiguration("cache2", RedisCacheConfiguration
						.defaultCacheConfig().entryTtl(Duration.ofMinutes(1)));
	}
}import org.springframework.boot.autoconfigure.cache.RedisCacheManagerBuilderCustomizer
import org.springframework.context.annotation.Bean
import org.springframework.context.annotation.Configuration
import org.springframework.data.redis.cache.RedisCacheConfiguration
import java.time.Duration
@Configuration(proxyBeanMethods = false)
class MyRedisCacheManagerConfiguration {
	@Bean
	fun myRedisCacheManagerBuilderCustomizer(): RedisCacheManagerBuilderCustomizer {
		return RedisCacheManagerBuilderCustomizer { builder ->
			builder
				.withCacheConfiguration(
					"cache1", RedisCacheConfiguration
						.defaultCacheConfig().entryTtl(Duration.ofSeconds(10))
				)
				.withCacheConfiguration(
					"cache2", RedisCacheConfiguration
						.defaultCacheConfig().entryTtl(Duration.ofMinutes(1))
				)
		}
	}
}咖啡因
Caffeine 是对 Guava 缓存的 Java 8 重写,取代了对 Guava 的支持。
如果存在咖啡因,则CaffeineCacheManager(由spring-boot-starter-cachestarter)是自动配置的。
可以通过在启动时创建缓存,方法是将spring.cache.cache-names属性,可以通过以下选项之一进行自定义(按指示的顺序):
- 
由 spring.cache.caffeine.spec
- 
一个 CaffeineSpecbean 被定义
- 
一个 Caffeinebean 被定义
例如,以下配置会创建cache1和cache2最大大小为 500 且生存时间为 10 分钟的缓存
- 
Properties 
- 
YAML 
spring.cache.cache-names=cache1,cache2
spring.cache.caffeine.spec=maximumSize=500,expireAfterAccess=600sspring:
  cache:
    cache-names: "cache1,cache2"
    caffeine:
      spec: "maximumSize=500,expireAfterAccess=600s"如果CacheLoaderbean 时,它会自动与CaffeineCacheManager.
由于CacheLoader将与缓存管理器管理的所有缓存相关联,则必须将其定义为CacheLoader<Object, Object>.
自动配置将忽略任何其他泛型类型。
缓存2k
Cache2k 是一个内存缓存。
如果存在 Cache2k spring 集成,则SpringCache2kCacheManager是自动配置的。
可以通过在启动时创建缓存,方法是将spring.cache.cache-names财产。
缓存默认值可以使用Cache2kBuilderCustomizer豆。
以下示例显示了一个定制器,该定制器将缓存的容量配置为 200 个条目,过期时间为 5 分钟:
- 
Java 
- 
Kotlin 
import java.util.concurrent.TimeUnit;
import org.springframework.boot.autoconfigure.cache.Cache2kBuilderCustomizer;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration(proxyBeanMethods = false)
public class MyCache2kDefaultsConfiguration {
	@Bean
	public Cache2kBuilderCustomizer myCache2kDefaultsCustomizer() {
		return (builder) -> builder.entryCapacity(200)
				.expireAfterWrite(5, TimeUnit.MINUTES);
	}
}import org.springframework.boot.autoconfigure.cache.Cache2kBuilderCustomizer
import org.springframework.context.annotation.Bean
import org.springframework.context.annotation.Configuration
import java.util.concurrent.TimeUnit
@Configuration(proxyBeanMethods = false)
class MyCache2kDefaultsConfiguration {
	@Bean
	fun myCache2kDefaultsCustomizer(): Cache2kBuilderCustomizer {
		return Cache2kBuilderCustomizer { builder ->
			builder.entryCapacity(200)
				.expireAfterWrite(5, TimeUnit.MINUTES)
		}
	}
}简单
如果找不到其他提供程序,则使用ConcurrentHashMap配置缓存存储时。如果您的应用程序中不存在缓存库,则这是默认值。默认情况下,缓存是根据需要创建的,但您可以通过设置cache-names财产。
例如,如果您只想要cache1和cache2caches,将cache-names属性如下:
- 
Properties 
- 
YAML 
spring.cache.cache-names=cache1,cache2spring:
  cache:
    cache-names: "cache1,cache2"如果这样做,并且应用程序使用未列出的缓存,则在运行时需要缓存时会失败,但在启动时不会失败。这类似于使用未声明缓存时“真实”缓存提供程序的行为方式。
没有
什么时候@EnableCaching,则还需要合适的缓存配置。
如果您有自定义的“org.springframework.cache.CacheManager”,请考虑在单独的@Configuration类,以便您可以在必要时覆盖它。
None 使用在测试中有用的无作实现,而切片测试默认通过@AutoConfigureCache.
如果需要在特定环境中使用无作缓存而不是自动配置的缓存管理器,请将缓存类型设置为none,如以下示例所示:
- 
Properties 
- 
YAML 
spring.cache.type=nonespring:
  cache:
    type: "none"