Spring Data Redis 为我们提供了下面的Serializer:GenericToStringSerializer、Jackson2JsonRedisSerializer、JacksonJsonRedisSerializer、JdkSerializationRedisSerializer、OxmSerializer、StringRedisSerializer。
序列化方式对比:
- JdkSerializationRedisSerializer: 使用JDK提供的序列化功能。 优点是反序列化时不需要提供类型信息(class),但缺点是需要实现Serializable接口,还有序列化后的结果非常庞大,是JSON格式的5倍左右,这样就会消耗redis服务器的大量内存。
- Jackson2JsonRedisSerializer: 使用Jackson库将对象序列化为JSON字符串。优点是速度快,序列化后的字符串短小精悍,不需要实现Serializable接口。但缺点也非常致命,那就是此类的构造函数中有一个类型参数,必须提供要序列化对象的类型信息(.class对象)。 通过查看源代码,发现其只在反序列化过程中用到了类型信息。
使用 FastJson2 来做。重写一些序列化器,并实现RedisSerializer接口。源码如下:
<dependency><groupId>com.alibaba.fastjson2</groupId><artifactId>fastjson2</artifactId><version>2.0.50</version>
</dependency>
FastJson2JsonRedisSerializer
package com.vipsoft.base.util;import com.alibaba.fastjson2.JSON;
import com.alibaba.fastjson2.JSONReader;
import com.alibaba.fastjson2.JSONWriter;
import com.alibaba.fastjson2.filter.Filter;import org.springframework.data.redis.serializer.RedisSerializer;
import org.springframework.data.redis.serializer.SerializationException;import java.nio.charset.Charset;/*** Redis使用FastJson序列化* * @author ruoyi*/
public class FastJson2JsonRedisSerializer<T> implements RedisSerializer<T>
{/*** 自动识别json对象白名单配置(仅允许解析的包名,范围越小越安全)*/public static final String[] JSON_WHITELIST_STR = { "org.springframework", "com.vipsoft" };public static final Charset DEFAULT_CHARSET = Charset.forName("UTF-8");static final Filter AUTO_TYPE_FILTER = JSONReader.autoTypeFilter(JSON_WHITELIST_STR);private Class<T> clazz;public FastJson2JsonRedisSerializer(Class<T> clazz){super();this.clazz = clazz;}@Overridepublic byte[] serialize(T t) throws SerializationException{if (t == null){return new byte[0];}return JSON.toJSONString(t, JSONWriter.Feature.WriteClassName).getBytes(DEFAULT_CHARSET);}@Overridepublic T deserialize(byte[] bytes) throws SerializationException{if (bytes == null || bytes.length <= 0){return null;}String str = new String(bytes, DEFAULT_CHARSET);return (T)JSON.parseObject(str, clazz, AUTO_TYPE_FILTER);}
}
Redis.config
package com.vipsoft.base.config;import com.cuwor.base.util.FastJson2JsonRedisSerializer;
import org.springframework.cache.annotation.EnableCaching;
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;@EnableCaching //开启缓存功能,作用于缓存配置类上或者作用于springboot启动类上
@Configuration
public class RedisConfig {/*** 创建一个RedisTemplate实例,用于操作Redis数据库。* 其中,redisTemplate是一个泛型为<String, Object>的模板对象,可以存储键值对数据;* @param factory factory是一个Redis连接工厂对象,用于建立与Redis服务器的连接* @return*/@Beanpublic RedisTemplate<String, Object> redisTemplate(RedisConnectionFactory factory) {RedisTemplate<String, Object> template = new RedisTemplate<>();template.setConnectionFactory(factory);FastJson2JsonRedisSerializer serializer = new FastJson2JsonRedisSerializer(Object.class);// 使用StringRedisSerializer来序列化和反序列化redis的key值template.setKeySerializer(new StringRedisSerializer());template.setValueSerializer(serializer);// Hash的key也采用StringRedisSerializer的序列化方式template.setHashKeySerializer(new StringRedisSerializer());template.setHashValueSerializer(serializer);template.afterPropertiesSet();return template;}
}
RedisUtil.java
package com.vipsoft.base.util;import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.ValueOperations;
import org.springframework.stereotype.Component;@Component
public class RedisUtil {@Autowiredprivate RedisTemplate redisTemplate;public <T> T get(String key) {ValueOperations<String, T> operation = redisTemplate.opsForValue();return operation.get(key);}public <T> boolean set(String key, T value) {try {redisTemplate.opsForValue().set(key, value);return true;} catch (Exception ex) {ex.printStackTrace();}return false;}}