直接上码
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.Cache;
import org.springframework.cache.CacheManager;
import org.springframework.cache.annotation.EnableCaching;
import org.springframework.cache.interceptor.CacheErrorHandler;
import org.springframework.cache.interceptor.KeyGenerator;
import org.springframework.cache.interceptor.SimpleKeyGenerator;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.convert.ConversionService;
import org.springframework.data.redis.cache.CacheKeyPrefix;
import org.springframework.data.redis.cache.RedisCacheConfiguration;
import org.springframework.data.redis.cache.RedisCacheManager;
import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.data.redis.serializer.Jackson2JsonRedisSerializer;
import org.springframework.data.redis.serializer.JdkSerializationRedisSerializer;
import org.springframework.data.redis.serializer.RedisSerializationContext;
import org.springframework.data.redis.serializer.StringRedisSerializer;
import org.springframework.format.support.DefaultFormattingConversionService;
import java.lang.reflect.Method;
import java.time.Duration;
import java.util.Collection;
import java.util.HashSet;
import java.util.Iterator;
import java.util.Set;
/* 启用缓存 */
@EnableCaching
@Configuration
public class SpringCacheConfig {
private static final Logger logger = LoggerFactory.getLogger(SpringCacheConfig.class);
@Autowired
private RedisConnectionFactory factory;
/**
* 最新的redis缓存管理器,需要连接工厂来构造
* 这个返回的缓存管理器,可以覆盖配置
*/
@Bean
public CacheManager cacheManager(){
/* 缓存名称集合,使用简单配置时好像不需要配置这个,显式配置需要添加 */
Set cacheNames = new HashSet<>();
cacheNames.add("cache1");
cacheNames.add("cache2");
cacheNames.add("cache3");
cacheNames.add("person");
/* 不知道啥意思 */
Duration duration = Duration.ZERO;
/* 是否缓存null值 */
boolean cacheNullValues = false;
/* 是否使用前缀,不使用key前缀时,只是用key作为redis键 */
boolean usePrefix = false;
/* 缓存键前缀,这是一个方法,根据缓存name生成key的方法,simple为name::,最后的存储key为keyPrefix加上key*/
CacheKeyPrefix keyPrefix = CacheKeyPrefix.simple();
/* 键序列化对,一般键都是字符串 */
RedisSerializationContext.SerializationPair keySerializationPair = RedisSerializationContext.SerializationPair.fromSerializer(new StringRedisSerializer());
/* 值序列化对,一般值都是对象,可以使用jdk的序列化机制,与Jackson序列化 */
RedisSerializationContext.SerializationPair
其实缓存这里无非牵扯一下几个问题:
1.序列化问题
一般的键都是以作为字符串来序列化,而值可以选择JDK序列化和Jackson序列化等各种形式,Jackson可以序列化为json,JDK序列化为二进制数据
2.命名空间问题
一个项目一般不会只存在一类数据需要缓存,多个不同种类数据要缓存时需要使用命名空间来进行区分
这里首先有一个usePrefix指定是否使用键前缀,如果不使用前缀,则所有缓存的key都是@Cacheable注解中指定的key
如果使用key前缀,则使用CacheKeyPrefix来指定如何从cacheName生成前缀
3.缓存形式
Redis中有多种数据结构,集合链表映射有序集合等,但实际上spring使用redis缓存时,还是使用了最普通的字符串存储
大致就是这么多