应用场景
我们希望通过缓存来减少对关系型数据库的查询次数,减轻数据库压力。在执行DAO类的select***()
, query***()
方法时,先从Redis
中查询有没有缓存数据,如果有则直接从Redis
拿到结果,如果没有再向数据库发起查询请求取数据。
序列化问题
要把domain object做为key-value对保存在redis中,就必须要解决对象的序列化问题。Spring Data Redis给我们提供了一些现成的方案:
JdkSerializationRedisSerializer
. 使用JDK提供的序列化功能。 优点是反序列化时不需要提供类型信息(class
),但缺点是序列化后的结果非常庞大,是JSON格式的5倍左右,这样就会消耗redis服务器的大量内存。Jackson2JsonRedisSerializer
. 使用Jackson
库将对象序列化为JSON字符串。优点是速度快,序列化后的字符串短小精悍。但缺点也非常致命,那就是此类的构造函数中有一个类型参数,必须提供要序列化对象的类型信息(.class
对象)。 通过查看源代码,发现其只在反序列化过程中用到了类型信息。
如果用方案一,就必须付出缓存多占用4倍内存的代价,实在承受不起。如果用方案二,则必须给每一种domain对象都配置一个Serializer,即如果我的应用里有100种domain对象,那就必须在spring配置文件中配置100个Jackson2JsonRedisSerializer
,这显然是不现实的。
通过google, 发现spring data redis项目中有一个#145 pull request, 而这个提交请求的内容正是解决Jackson
必须提供类型信息的问题。然而不幸的是这个请求还没有被merge
。但我们可以把代码copy一下放到自己的项目中:
/**
* @author Christoph Strobl
* @since 1.6
*/
public class GenericJackson2JsonRedisSerializer