1.1 可以通过jedis,代码的方式手动将其传入redis作为缓存;
1.2 也可以通过注解的方式,和spring boot整合,通过@cacheable...的方式自动存入redis(本文的探讨方式)
例如:缓存管理器的自定义方式
@Bean //spring boot1.x版本的使用方式
public CacheManager cacheManager(RedisTemplate redisTemplate) {
RedisCacheManager cacheManager= new RedisCacheManager(redisTemplate);
cacheManager.setDefaultExpiration(60);
Map expiresMap=new HashMap<>();
expiresMap.put("Product",5L);
cacheManager.setExpires(expiresMap);
return cacheManager;
}
到了2.x版本,没有这个构造方法,该方式已经不能使用;
思路:
1.编写RedisConfig配置类----配置类里面重构cacheManager和redisTemplate; 后期可以在该类中设置key的生成策略等...
2.实现对象的缓存,定义自己的序列化和反序列化器。(必须定义自己的)
在redisConfig类中不要导入:
import com.alibaba.fastjson.support.spring.FastJsonRedisSerializer;//不要导入
导入:
import zmc.leon.mcd.Util.FastJsonRedisSerializer;//自定义的序列化反序列化器
3.spring boot+mybatis的controller、service、dao层的编写(省略)
RedisConfig.java
package zmc.leon.mcd.Config;
//import com.alibaba.fastjson.support.spring.FastJsonRedisSerializer;
import com.alibaba.fastjson.parser.ParserConfig;
import com.fasterxml.jackson.annotation.JsonAutoDetect;
import com.fasterxml.jackson.annotation.PropertyAccessor;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.SerializationFeature;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.cache.CacheManager;
import org.springframework.cache.annotation.CachingConfigurerSupport;
import org.springframework.cache.annotation.EnableCaching;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary;
import org.springframework.data.redis.cache.RedisCacheConfiguration;
import org.springframework.data.redis.cache.RedisCacheManager;
import org.springframework.data.redis.cache.RedisCacheWriter;
import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.serializer.*;
import zmc.leon.mcd.Util.FastJsonRedisSerializer;
import javax.crypto.KeyGenerator;
import java.lang.reflect.Method;
import java.time.Duration;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;
@Configuration
@EnableCaching
public class RedisConfig extends CachingConfigurerSupport {
/**
* 重写Redis序列化方式,使用Json方式:
* 当我们的数据存储到Redis的时候,我们的键(key)和值(value)都是通过Spring提供的Serializer序列化到数据库的。RedisTemplate默认使用的是JdkSerializationRedisSerializer,StringRedisTemplate默认使用的是StringRedisSerializer。
* Spring Data JPA为我们提供了下面的Serializer:
* GenericToStringSerializer、Jackson2JsonRedisSerializer、JacksonJsonRedisSerializer、JdkSerializationRedisSerializer、OxmSerializer、StringRedisSerializer。
* 在此我们将自己配置RedisTemplate并定义Serializer。
*
*/
// 存入redis时,默认使用的是JdkSerializationRedisSerializer,使得存入的数据全部序列化了,所需自定义一个RedisTemplate,使用其他序列化方式
//当redis依赖包导入的时候,默认的cache即可自动变成redis模式;如果只是导入cache的依赖,则默认的是simpleCacheManager;
// 使用redis缓存时,RedisCacheManager生成RedisCache后生成缓存时默认使用JdkSerializationRedisSerializer序列化(cache存储的时候)
//当ioc容器内没有自定义的缓存管理器的时候---默认使用自带的;
//当通过@Bean在ioc容器中注入了以下管理器,则会使用自定义的管理器;
// @Bean
// public CacheManager cacheManager(RedisConnectionFactory factory) {
// RedisCacheConfiguration config = RedisCacheConfiguration.defaultCacheConfig(); // 生成一个默认配置,通过config对象即可对缓存进行自定义配置
// config = config.entryTtl(Duration.ofMinutes(1)) // 设置缓存的默认过期时间,也是使用Duration设置
// .disableCachingNullValues(); // 不缓存空值
//
// // 设置一个初始化的缓存空间set集合
// Set cacheNames = new HashSet<>();
// cacheNames.add("my-redis-cache1");
// cacheNames.add("my-redis-cache2");
//
// // 对每个缓存空间应用不同的配置
// Map configMap = new HashMap<>();
// configMap.put("my-redis-cache1", config);
// configMap.put("my-redis-cache2", config.entryTtl(Duration.ofSeconds(120)));
//
// RedisCacheManager cacheManager = RedisCacheManager.builder(factory) // 使用自定义的缓存配置初始化一个cacheManager
// .initialCacheNames(cacheNames) // 注意这两句的调用顺序,一定要先调用该方法设置初始化的缓存名,再初始化相关的配置
// .withInitialCacheConfigurations(configMap)
// .build();
// return cacheManager;
// }
@Bean
@Primary//当有多个管理器的时候,必须使用该注解在一个管理器上注释:表示该管理器为默认的管理器
public CacheManager cacheManager(RedisConnectionFactory connectionFactory) {
//初始化一个RedisCacheWriter
RedisCacheWriter redisCacheWriter = RedisCacheWriter.nonLockingRedisCacheWriter(connectionFactory);
//序列化方式1
//设置CacheManager的值序列化方式为JdkSerializationRedisSerializer,但其实RedisCacheConfiguration默认就是使用StringRedisSerializer序列化key,JdkSerializationRedisSerializer序列化value,所以以下(4行)注释代码为默认实现
// ClassLoader loader = this.getClass().getClassLoader();
// JdkSerializationRedisSerializer jdkSerializer = new JdkSerializationRedisSerializer(loader);
// RedisSerializationContext.SerializationPair
FastJsonRediaSerializer.java
package zmc.leon.mcd.Util;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.serializer.SerializerFeature;
import org.springframework.data.redis.serializer.RedisSerializer;
import org.springframework.data.redis.serializer.SerializationException;
import java.nio.charset.Charset;
/*
要实现对象的缓存,定义自己的序列化和反序列化器。使用阿里的fastjson来实现的比较多。
*/
public class FastJsonRedisSerializer implements RedisSerializer {
private static final Charset DEFAULT_CHARSET = Charset.forName("UTF-8");
private Class clazz;
public FastJsonRedisSerializer(Class clazz) {
super();
this.clazz = clazz;
}
@Override
public byte[] serialize(T t) throws SerializationException {
if (null == t) {
return new byte[0];
}
return JSON.toJSONString(t, SerializerFeature.WriteClassName).getBytes(DEFAULT_CHARSET);
}
@Override
public T deserialize(byte[] bytes) throws SerializationException {
if (null == bytes || bytes.length <= 0) {
return null;
}
String str = new String(bytes, DEFAULT_CHARSET);
return (T) JSON.parseObject(str, clazz);
}
}
注意:
1.一定要导入自己的util包
import zmc.leon.mcd.Util.FastJsonRedisSerializer;
2.缓存管理器中一定要加入(白名单),其中的包名:为自己的bean类的所在包
ParserConfig.getGlobalInstance().addAccept("zmc.leon.mcd.entity.");
没有的话会有以下异常:
com.alibaba.fastjson.JSONException: autoType is not support
具体解释请关注:
https://blog.csdn.net/u012240455/article/details/80538540