目录
[sync = true](#sync = true)
SpringCache
集成与管理缓存,它通过声明式注解和统一的 API,将缓存逻辑与业务逻辑解耦,支持多种缓存实现(如 Redis、Ehcache、Caffeine 等),并提供了灵活的配置选项。
引入
XML
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-cache</artifactId>
</dependency>
@EnableCaching开启缓存
自动配置
CacheAutoConfiguration 依据缓存类型,自动配置缓存。
CacheConfigurations 映射 相应的缓存配置
java
static {
Map<CacheType, Class<?>> mappings = new EnumMap(CacheType.class);
mappings.put(CacheType.GENERIC, GenericCacheConfiguration.class);
mappings.put(CacheType.EHCACHE, EhCacheCacheConfiguration.class);
mappings.put(CacheType.HAZELCAST, HazelcastCacheConfiguration.class);
mappings.put(CacheType.INFINISPAN, InfinispanCacheConfiguration.class);
mappings.put(CacheType.JCACHE, JCacheCacheConfiguration.class);
mappings.put(CacheType.COUCHBASE, CouchbaseCacheConfiguration.class);
mappings.put(CacheType.REDIS, RedisCacheConfiguration.class);
mappings.put(CacheType.CAFFEINE, CaffeineCacheConfiguration.class);
mappings.put(CacheType.SIMPLE, SimpleCacheConfiguration.class);
mappings.put(CacheType.NONE, NoOpCacheConfiguration.class);
MAPPINGS = Collections.unmodifiableMap(mappings);
}
RedisCacheConfiguration 为每一个缓存"分区"提供初始化,并返回Manager
java
@Bean
public RedisCacheManager cacheManager(RedisConnectionFactory redisConnectionFactory, ResourceLoader resourceLoader) {
RedisCacheManager.RedisCacheManagerBuilder builder = RedisCacheManager.builder(redisConnectionFactory).cacheDefaults(this.determineConfiguration(resourceLoader.getClassLoader()));
List<String> cacheNames = this.cacheProperties.getCacheNames();
if (!cacheNames.isEmpty()) {
builder.initialCacheNames(new LinkedHashSet(cacheNames));
}
return (RedisCacheManager)this.customizerInvoker.customize(builder.build());
}
Manager为每一个分区进行默认配置defaultCacheConfiguration
java
public RedisCacheManagerBuilder initialCacheNames(Set<String> cacheNames) {
Assert.notNull(cacheNames, "CacheNames must not be null!");
Map<String, RedisCacheConfiguration> cacheConfigMap = new LinkedHashMap(cacheNames.size());
cacheNames.forEach((it) -> {
RedisCacheConfiguration var10000 = (RedisCacheConfiguration)cacheConfigMap.put(it, this.defaultCacheConfiguration);
});
return this.withInitialCacheConfigurations(cacheConfigMap);
}
redisCacheConfiguration 若为空,这采用默认配置
java
private org.springframework.data.redis.cache.RedisCacheConfiguration determineConfiguration(ClassLoader classLoader) {
if (this.redisCacheConfiguration != null) {
return this.redisCacheConfiguration;
} else {
CacheProperties.Redis redisProperties = this.cacheProperties.getRedis();
org.springframework.data.redis.cache.RedisCacheConfiguration config = org.springframework.data.redis.cache.RedisCacheConfiguration.defaultCacheConfig();
config = config.serializeValuesWith(SerializationPair.fromSerializer(new JdkSerializationRedisSerializer(classLoader)));
if (redisProperties.getTimeToLive() != null) {
config = config.entryTtl(redisProperties.getTimeToLive());
}
if (redisProperties.getKeyPrefix() != null) {
config = config.prefixKeysWith(redisProperties.getKeyPrefix());
}
if (!redisProperties.isCacheNullValues()) {
config = config.disableCachingNullValues();
}
if (!redisProperties.isUseKeyPrefix()) {
config = config.disableKeyPrefix();
}
return config;
}
}
自定义配置
容器中注入一个 RedisCacheConfiguration
java
@EnableCaching
@Configuration
public class MyCacheConfig {
@Autowired
private CacheProperties cacheProperties;
@Bean
RedisCacheConfiguration redisCacheConfiguration(){
RedisCacheConfiguration config = RedisCacheConfiguration.defaultCacheConfig();
config = config.serializeKeysWith(RedisSerializationContext.SerializationPair.fromSerializer(new StringRedisSerializer()));
//Json序列化
config = config.serializeValuesWith(RedisSerializationContext.SerializationPair.fromSerializer(new GenericFastJsonRedisSerializer()));
//使配置文件生效
CacheProperties.Redis redisProperties = this.cacheProperties.getRedis();
if (redisProperties.getTimeToLive() != null) {
config = config.entryTtl(redisProperties.getTimeToLive());
}
if (redisProperties.getKeyPrefix() != null) {
config = config.prefixKeysWith(redisProperties.getKeyPrefix());
}
if (!redisProperties.isCacheNullValues()) {
config = config.disableCachingNullValues();
}
if (!redisProperties.isUseKeyPrefix()) {
config = config.disableKeyPrefix();
}
return config;
}
}
R
spring.cache.type=redis
#缓存空值,防止缓存穿透
spring.cache.redis.cache-null-values=true
#spring.cache.redis.time-to-live=3600000
#spring.cache.redis.key-prefix=CACHE_
spring.cache.redis.use-key-prefix=true
注解
@Cacheable
缓存方法返回值,若缓存命中则直接返回结果,否则执行方法并缓存结果。
键名 默认格式 缓存名::SimpleKey[param1, param2,...],支持 SpEL 表达式
java
@Cacheable(key = "#id") // 使用参数 id 作为键
@Cacheable(key = "#user.id") // 使用对象属性作为键
@Cacheable(key = "#root.methodName") // 使用方法名作为键[1,3](@ref)
默认使用jdk序列化机制,可在自定义配置中使用Json序列化器

@CacheEvict
清除缓存数据

sync = true
同步锁,本地锁,仅@Cacheable支持
java
@Cacheable(cacheNames = "category",key = "#root.methodName",sync = true)