您好,欢迎来到三六零分类信息网!老站,搜索引擎当天收录,欢迎发信息

SpringBoot怎么自定义Redis实现缓存序列化

2025/4/18 23:36:40发布23次查看
1、自定义redistemplate1.1、redis api默认序列化机制基于api的redis缓存实现是使用redistemplate模板进行数据缓存操作的,这里打开redistemplate类,查看该类的源码信息
public class redistemplate<k, v> extends redisaccessor implements redisoperations<k, v>, beanclassloaderaware { // 声明了key、value的各种序列化方式,初始值为空 @nullable private redisserializer keyserializer = null; @nullable private redisserializer valueserializer = null; @nullable private redisserializer hashkeyserializer = null; @nullable private redisserializer hashvalueserializer = null;... // 进行默认序列化方式设置,设置为jdk序列化方式 public void afterpropertiesset() { super.afterpropertiesset(); boolean defaultused = false; if (this.defaultserializer == null) { this.defaultserializer = new jdkserializationredisserializer( this.classloader != null ? this.classloader : this.getclass().getclassloader()); } ... } ...}
从上述redistemplate核心源码可以看出,在redistemplate内部声明了缓存数据key、value的各种序列化方式,且初始值都为空;在afterpropertiesset()方法中,判断如果默认序列化参数defaultserializer为空,将数据的默认序列化方式设置为jdkserializationredisserializer
根据上述源码信息的分析,可以得到以下两个重要的结论:
(1)使用redistemplate进行redis数据缓存操作时,内部默认使用的是jdkserializationredisserializer序列化方式,所以进行数据缓存的实体类必须实现jdk自带的序列化接口(例如serializable);
(2)使用redistemplate进行redis数据缓存操作时,如果自定义了缓存序列化方式defaultserializer,那么将使用自定义的序列化方式。
另外,在redistemplate类源码中,看到的缓存数据key、value的各种序列化类型都是redisserializer。进入redisserializer源码查看redisserializer支持的序列化方式(进入该类后,使用ctrl+alt+左键单击类名查看)
可以看出,redisserializer是一个redis序列化接口,默认有6个实现类,这6个实现类代表了6种不同的数据序列化方式。其中,jdkserializationredisserializer是jdk自带的,也是redistemplate内部默认使用的数据序列化方式,开发者可以根据需要选择其他支持的序列化方式(例如json方式)
1.2、自定义redistemplate序列化机制在项目中引入redis依赖后,spring boot提供的redisautoconfiguration自动配置会生效。打开redisautoconfiguration类,查看内部源码中关于redistemplate的定义方式
public class redisautoconfiguration { @bean @conditionalonmissingbean( name = {"redistemplate"} ) public redistemplate<object, object> redistemplate(redisconnectionfactory redisconnectionfactory) throws unknownhostexception { redistemplate<object, object> template = new redistemplate(); template.setconnectionfactory(redisconnectionfactory); return template; }...}
从上述redisautoconfiguration核心源码中可以看出,在redis自动配置类中,通过redis连接工厂redisconnectionfactory初始化了一个redistemplate;该类上方添加了@conditionalonmissingbean注解(顾名思义,当某个bean不存在时生效),用来表明如果开发者自定义了一个名为redistemplate的bean,则该默认初始化的redistemplate不会生效。
如果想要使用自定义序列化方式的redistemplate进行数据缓存操作,可以参考上述核心代码创建一个名为redistemplate的bean组件,并在该组件中设置对应的序列化方式即可
接下来,在项目中创建名为com.lagou.config的包,在该包下创建一个redis自定义配置类redisconfig,并按照上述思路自定义名为redistemplate的bean组件
@configurationpublic class redisconfig { // 自定义redistemplate @bean public redistemplate<object, object> redistemplate(redisconnectionfactory redisconnectionfactory) { redistemplate<object, object> template = new redistemplate<>(); template.setconnectionfactory(redisconnectionfactory); // 创建一个json格式序列化对象,对缓存数据的key和value进行转换 jackson2jsonredisserializer jackson2jsonredisserializer = new jackson2jsonredisserializer(object.class); // 解决查询缓存转换异常的问题 objectmapper om = new objectmapper(); om.setvisibility(propertyaccessor.all, jsonautodetect.visibility.any); om.enabledefaulttyping(objectmapper.defaulttyping.non_final); jackson2jsonredisserializer.setobjectmapper(om); // 设置redistemplate模板api序列化方式为json template.setdefaultserializer(jackson2jsonredisserializer); return template; }}
通过@configuration注解定义了一个redisconfig配置类,并使用@bean注解注入了一个默认名称为方法名的redistemplate组件(注意,该bean组件名称必须是redistemplate)。在定义的bean组件中,自定义了一个redistemplate,使用自定义的jackson2jsonredisserializer数据序列化方式;在定制序列化方式中,定义了一个objectmapper用于进行数据转换设置
1.3、效果测试
可以看出,执行findbyid()方法正确查询出用户评论信息comment,重复进行同样的查询操作,数据库只执行了一次sql语句,这说明定制的redis缓存生效。
使用redis客户端可视化管理工具redis desktop manager查看缓存数据 :
执行findbyid()方法查询出用户评论信息comment正确存储到了redis缓存库中,且缓存到redis服务的数据已经使用了json格式存储展示,查看和管理也非常方便,说明自定义的redis api模板工具redistemplate生效
2、自定义rediscachemanager刚刚针对基于 api方式的redistemplate进行了自定义序列化方式的改进,从而实现了json序列化方式缓存数据,但是这种自定义的redistemplate对于基于注解的redis缓存来说,是没有作用的。
接下来,针对基于注解的redis缓存机制和自定义序列化方式进行讲解
2.1、redis注解默认序列化机制打开spring boot整合redis组件提供的缓存自动配置类rediscacheconfiguration(org.springframework.boot.autoconfigure.cache包下的),查看该类的源码信息,其核心代码如下
@configurationclass rediscacheconfiguration { @bean public rediscachemanager cachemanager(redisconnectionfactory redisconnectionfactory, resourceloader resourceloader) { rediscachemanagerbuilder builder = rediscachemanager .builder(redisconnectionfactory) .cachedefaults(this.determineconfiguration(resourceloader.getclassloader())); list<string> cachenames = this.cacheproperties.getcachenames(); if (!cachenames.isempty()) { builder.initialcachenames(new linkedhashset(cachenames)); } return (rediscachemanager) this.customizerinvoker.customize(builder.build()); } private org.springframework.data.redis.cache.rediscacheconfiguration determineconfiguration(classloader classloader) { if (this.rediscacheconfiguration != null) { return this.rediscacheconfiguration; } else { redis redisproperties = this.cacheproperties.getredis(); org.springframework.data.redis.cache.rediscacheconfiguration config = org.springframework.data.redis.cache.rediscacheconfiguration.defaultcacheconfig(); config = config.serializevalueswith(serializationpair.fromserializer( new jdkserializationredisserializer(classloader))); ... return config; } }}
从上述核心源码中可以看出,同redistemplate核心源码类似,rediscacheconfiguration内部同样通过redis连接工厂redisconnectionfactory定义了一个缓存管理器rediscachemanager;同时定制rediscachemanager时,也默认使用了jdkserializationredisserializer序列化方式。
如果想要使用自定义序列化方式的rediscachemanager进行数据缓存操作,可以参考上述核心代码创建一个名为cachemanager的bean组件,并在该组件中设置对应的序列化方式即可
在spring boot 2.x版本中,rediscachemanager是独立构建的。因此,在springboot 2.x版本中,对redistemplate进行自定义序列化机制构建后,仍然无法对rediscachemanager内部默认序列化机制进行覆盖(这也就解释了基 于注解的redis缓存实现仍然会使用jdk默认序列化机制的原因),想要基于注解的redis缓存实现也使用自定义序列化机制,需要自定义rediscachemanager
2.2、自定义rediscachemanager在项目的redis配置类redisconfig中,按照上一步分析的定制方法自定义名为cachemanager的bean组件
@bean public rediscachemanager cachemanager(redisconnectionfactory redisconnectionfactory) { // 分别创建string和json格式序列化对象,对缓存数据key和value进行转换 redisserializer<string> strserializer = new stringredisserializer(); jackson2jsonredisserializer jacksonserial = new jackson2jsonredisserializer(object.class); // 解决查询缓存转换异常的问题 objectmapper om = new objectmapper(); om.setvisibility(propertyaccessor.all, jsonautodetect.visibility.any); // om.enabledefaulttyping(objectmapper.defaulttyping.non_final); om.activatedefaulttyping(laissezfairesubtypevalidator.instance, objectmapper.defaulttyping.non_final, jsontypeinfo.as.property); // 上面注释过时代码的替代方法 jacksonserial.setobjectmapper(om); // 定制缓存数据序列化方式及时效 rediscacheconfiguration config = rediscacheconfiguration.defaultcacheconfig() .entryttl(duration.ofdays(1)) // 设置缓存数据的时效(设置为了1天) .serializekeyswith(redisserializationcontext.serializationpair .fromserializer(strserializer)) // 对当前对象的key使用strserializer这个序列化对象,进行转换 .serializevalueswith(redisserializationcontext.serializationpair .fromserializer(jacksonserial)) // 对value使用jacksonserial这个序列化对象,进行转换 .disablecachingnullvalues(); rediscachemanager cachemanager = rediscachemanager .builder(redisconnectionfactory).cachedefaults(config).build(); return cachemanager; }
上述代码中,在redisconfig配置类中使用@bean注解注入了一个默认名称为方法名的cachemanager组件。在定义的bean组件中,通过rediscacheconfiguration对缓存数据的key和value分别进行了序列化方式的定制,其中缓存数据的key定制为stringredisserializer(即string格式),而value定制为了jackson2jsonredisserializer(即json格式),同时还使用entryttl(duration.ofdays(1))方法将缓存数据有效期设置为1天
完成基于注解的redis缓存管理器rediscachemanager定制后,可以对该缓存管理器的效果进行测试(使用自定义序列化机制的rediscachemanager测试时,实体类可以不用实现序列化接口)
以上就是springboot怎么自定义redis实现缓存序列化的详细内容。
该用户其它信息

VIP推荐

免费发布信息,免费发布B2B信息网站平台 - 三六零分类信息网 沪ICP备09012988号-2
企业名录 Product