1,准备
①,一个linux虚拟机,安装好docker,再安装redis镜像,然后启动redis容器
②,身为程序员linux不可不玩,而docker就是一个强有力的工具
③,springboot版本2.0.2.RELEASE
2,redis配置
import com.fasterxml.jackson.annotation.JsonAutoDetect;
import com.fasterxml.jackson.annotation.PropertyAccessor;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.springframework.cache.annotation.EnableCaching;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.cache.RedisCacheConfiguration;
import org.springframework.data.redis.serializer.Jackson2JsonRedisSerializer;
import org.springframework.data.redis.serializer.RedisSerializationContext;
import java.time.Duration;
@EnableCaching
@Configuration
public class CacheConfig {
@Bean
public RedisCacheConfiguration redisCacheConfiguration(){
RedisCacheConfiguration configuration = RedisCacheConfiguration.defaultCacheConfig();
Jackson2JsonRedisSerializer<Object> jackson2JsonRedisSerializer = new
Jackson2JsonRedisSerializer<Object>(Object.class);
ObjectMapper om = new ObjectMapper();
om.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);
// 将类型序列化到属性json字符串中
om.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL);
jackson2JsonRedisSerializer.setObjectMapper(om);
configuration = configuration.serializeValuesWith(RedisSerializationContext.SerializationPair.
fromSerializer(jackson2JsonRedisSerializer))
.entryTtl(Duration.ofDays(30));
return configuration;
}
}
3,application.properties 配置
spring.redis.host=192.168.43.28
spring.redis.port=6379
4,RedisCacheConfiguration 生效
//使用RedisCacheManager 用于创建cache
@Bean
public RedisCacheManager cacheManager(RedisConnectionFactory redisConnectionFactory,
ResourceLoader resourceLoader) {
RedisCacheManagerBuilder builder = RedisCacheManager
.builder(redisConnectionFactory)
.cacheDefaults(determineConfiguration(resourceLoader.getClassLoader()));
List<String> cacheNames = this.cacheProperties.getCacheNames();
if (!cacheNames.isEmpty()) {
builder.initialCacheNames(new LinkedHashSet<>(cacheNames));
}
return this.customizerInvoker.customize(builder.build());
}
//RedisCacheManager 创建cache的方法
protected RedisCache createRedisCache(String name, @Nullable RedisCacheConfiguration cacheConfig) {
return new RedisCache(name, cacheWriter, cacheConfig != null ? cacheConfig : defaultCacheConfig);
}
5,RedisCache 创建缓存的流程
//①,根据一定的策略生成缓存的key
protected String createCacheKey(Object key) {
String convertedKey = convertKey(key);
if (!cacheConfig.usePrefix()) {
return convertedKey;
}
return prefixCacheKey(convertedKey);
}
//②,先尝试获取缓存
public byte[] get(String name, byte[] key) {
Assert.notNull(name, "Name must not be null!");
Assert.notNull(key, "Key must not be null!");
return execute(name, connection -> connection.get(key));
}
//③,获取不到就执行目标方法,并将返回结果放入缓存
public void put(Object key, @Nullable Object value) {
Object cacheValue = preProcessCacheValue(value);
if (!isAllowNullValues() && cacheValue == null) {
throw new IllegalArgumentException(String.format(
"Cache '%s' does not allow 'null' values. Avoid storing null via '@Cacheable(unless=\"#result == null\")' or configure RedisCache to allow 'null' via RedisCacheConfiguration.",
name));
}
cacheWriter.put(name, createAndConvertCacheKey(key), serializeCacheValue(cacheValue), cacheConfig.getTtl());
}
6,获取缓存的过程
//①,根据一定的策略生成缓存的key
protected String createCacheKey(Object key) {
String convertedKey = convertKey(key);
if (!cacheConfig.usePrefix()) {
return convertedKey;
}
return prefixCacheKey(convertedKey);
}
//②,尝试根据可以获取对应的缓存
@Override
public byte[] get(String name, byte[] key) {
Assert.notNull(name, "Name must not be null!");
Assert.notNull(key, "Key must not be null!");
return execute(name, connection -> connection.get(key));
}
//③,获取成功则不执行目标方法,直接将缓存返回
7,缓存在redis的样子
①,注意,缓存的数据要带有缓存的类型,否则redis缓存反序列化成对应pojo会失败,只要按上面的CacheConfig配置好RedisCacheConfiguration 即可