在SpringBoot的redisTemplate在redis当中存入数据的时候,能看到key和value被序列化,我们基本上很难判断这个缓存是干什么用的,所以我们需要修复它:
解决这个问题我们需要自定义一个序列化器RedisJsonSerializerImpl,其中还有一个内部类:
static class SerializerObject {
public SerializerObject() {
}
public SerializerObject(String className, String jsonObject) {
this.className = className;
this.jsonObject = jsonObject;
}
private String className;
private String jsonObject;
public String getClassName() {
return className;
}
public SerializerObject setClassName(String className) {
this.className = className;
return this;
}
public String getJsonObject() {
return jsonObject;
}
public SerializerObject setJsonObject(String jsonObject) {
this.jsonObject = jsonObject;
return this;
}
@Override
public String toString() {
return JSON.toJSONString(this);
}
}
RedisJsonSerializerImpl实现了org.springframework.data.redis.serializer.RedisSerializer,并且实现下面两个方法,serialize方法定义了序列化对象(将对象从Java程序中存入缓存中),deserialize用户反序列化对象(将缓存中读取对象并转换为Java对象):
@Override
public byte[] serialize(T t) throws SerializationException {
// 如果对象为空,那么就返回一个空的byte数组就好了
if (null == t) return new byte[0];
// 获取序列化后的对象
String resultObject = new SerializerObject(t.getClass().getName(), JSON.toJSONString(t)).toString();
return resultObject.getBytes(StandardCharsets.UTF_8);
}
@Override
public T deserialize(byte[] bytes) throws SerializationException {
if (CollectionUtils.isNull(bytes)) return null;
// 将其反序列化成一个字符串
SerializerObject resultObject = JSON.parseObject(new String(bytes, StandardCharsets.UTF_8), SerializerObject.class);
try {
return JSON.parseObject(resultObject.jsonObject, (Type) Class.forName(resultObject.className));
} catch (ClassNotFoundException e) {
log.error("类未找到:" + resultObject.className, e);
return null;
}
}
类完整的代码如下:
package love.xiaohh.cost.utils.storage; import com.alibaba.fastjson.JSON; import love.xiaohh.cost.utils.CollectionUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.data.redis.serializer.RedisSerializer; import org.springframework.data.redis.serializer.SerializationException; import java.lang.reflect.Type; import java.nio.charset.StandardCharsets; public class RedisJsonSerializerImplimplements RedisSerializer { private static final Logger log = LoggerFactory.getLogger(RedisJsonSerializerImpl.class); @Override public byte[] serialize(T t) throws SerializationException { // 如果对象为空,那么就返回一个空的byte数组就好了 if (null == t) return new byte[0]; // 获取序列化后的对象 String resultObject = new SerializerObject(t.getClass().getName(), JSON.toJSONString(t)).toString(); return resultObject.getBytes(StandardCharsets.UTF_8); } @Override public T deserialize(byte[] bytes) throws SerializationException { if (CollectionUtils.isNull(bytes)) return null; // 将其反序列化成一个字符串 SerializerObject resultObject = JSON.parseObject(new String(bytes, StandardCharsets.UTF_8), SerializerObject.class); try { return JSON.parseObject(resultObject.jsonObject, (Type) Class.forName(resultObject.className)); } catch (ClassNotFoundException e) { log.error("类未找到:" + resultObject.className, e); return null; } } static class SerializerObject { public SerializerObject() { } public SerializerObject(String className, String jsonObject) { this.className = className; this.jsonObject = jsonObject; } private String className; private String jsonObject; public String getClassName() { return className; } public SerializerObject setClassName(String className) { this.className = className; return this; } public String getJsonObject() { return jsonObject; } public SerializerObject setJsonObject(String jsonObject) { this.jsonObject = jsonObject; return this; } @Override public String toString() { return JSON.toJSONString(this); } } }
然后我们定义一个RedisConfig,将设置这个序列化对象:
package love.xiaohh.cost.configurations;
import love.xiaohh.cost.constants.Constants;
import love.xiaohh.cost.utils.storage.RedisJsonSerializerImpl;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.serializer.StringRedisSerializer;
@Configuration
public class RedisConfig {
@Bean(Constants.REDISTEMPLATE)
public RedisTemplate redisTemplate(RedisConnectionFactory redisConnectionFactory) {
// 缓存操作对象
RedisTemplate redisTemplate = new RedisTemplate();
// 设置链接工厂
redisTemplate.setConnectionFactory(redisConnectionFactory);
// 键的序列化器
redisTemplate.setKeySerializer(new StringRedisSerializer());
// 值的序列化器,这里我们用的是我们自己配置好的
redisTemplate.setValueSerializer(new RedisJsonSerializerImpl<>());
return redisTemplate;
}
}
其中key的序列化器使用自带的 StringRedisSerializer,然后value序列化使用我们自定义的 RedisJsonSerializerImpl,这个类就定义好了,我们运行看看效果:
可以发现key和value的可观测性提高了许多,好了下课



