当前位置: 首页 > 科技观察

从零搭建SpringBoot脚手架:集成Redis作为缓存

时间:2023-03-20 13:03:56 科技观察

前言今天我们也来集成一下缓存。缓存是一个系统应用的必备功能,除了减轻数据库的压力外。在存储一些短期数据的场景中也有重要的作用,比如存储用户token,短信验证码等。目前缓存的种类还是很多的,比如EHCACHE,HAZELCAST,CAFFEINE,COUCHBASE,REDIS被整合到本文中。接下来我们将在kono脚手架项目中集成SpringCache和Redis。Gitee:https://gitee.com/felord/konoday05branchGitHub:https://github.com/NotFound403/konoday05branch2.集成目标使项目具有缓存功能,同时修改JDK默认序列化为JacksonSerialize来存储一些对象,同时实现一些特定的个性化缓存空间,以满足不同场景下不同的缓存TTL时间需求。3、依赖集成目前只需要引入以下依赖:>org.springframework.bootspring-boot-starter-cacheorg.apache.commonscommons-pool2spring-data-redis默认使用高性能的lettuce客户端实现,当然你也可以换成旧的jedis。4、缓存和Redis配置缓存和Redis相关的配置项分别是spring.cache和spring.redis开头的配置。这里比较简单的配置是:spring:redis:host:localhostport:6379cache:#type:REDISredis:#GlobalExpirationtime-time-to-live:1205RedisTemplatePersonalization默认会在SpringIoC中注入两个模板类供我们使用,需要个性化配置才能满足实际开发。一种是RedisTemplate,主要用于对象缓存。它默认使用JDK序列化。我们需要改变它的序列化方式来解决一些问题,比如Java8日期问题和JSON序列化问题。我们需要重写它。/***Redis的一些自定义配置。**@authorfelord.cn*@since2020/8/1720:39*/@ConditionalOnClass(ObjectMapper.class)@Configuration(proxyBeanMethods=false)publicclassRedisConfiguration{/***Redistemplateredistemplate.**@paramredisConnectionFactorytheredisconnectionfactory*@returntheredistemplate*/@Bean("redisTemplate")使用Jackson2JsonRedisSerialize替换默认序列化Jackson2JsonRedisSerializerjackson2JsonRedisSerializer=initJacksonSerializer();//设置value和key的序列化规则);returntemplate;}/***处理redis序列化问题*@returnJackson2JsonRedisSerializer*/privateJackson2JsonRedisSerializerinitJacksonSerializer(){Jackson2JsonRedisSerializerjackson2JsonRedisSerializer=newJackson2JsonRedisSerializer<>(Object.class);ObjectMapperom=newObjectMapper();om.setVisibility(PropertyAccessor.ALL,JsonAutoDetect.Visibility.ANY);//以下替换旧版本om.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL);om.activateDefaultTyping(om.getPolymorphicTypeValidator(),ObjectMapper.DefaultTyping.NON_FINAL);//bugFixJackson2反序列化数据处理LocalDateTime类型错误om.disable(SerializationFeature.WRITE_DATE_KEYS_AS_TIMESTAMPS);/java/8时间支持om.registerModule(newJavaTimeModule());jackson2JsonRedisSerializer.setObjectMapper(om);returnjackson2JsonRedisSerializer;}}另一个是StringRedisTemplate,主要处理key和value都是字符串的缓存。使用默认就好了6.缓存个性化使用SpringCache作为缓存有时候会出现针对不同key设置不??同过期时间的场景。比如我想设置JwtToken一周后过期,我想设置验证码五分钟后过期。如何做到这一点?我们需要对RedisCacheManager的配置进行个性化设置。首先我通过枚举来定义这些缓存和它们的TTL时间。例如:/***缓存定义枚举**@authorfelord.cn*@seecn.felord.kono.configuration.CacheConfiguration*@since2020/8/1721:40*/publicenumCacheEnum{/***用户jwttoken缓存空间ttl7天*/JWT_TOKEN_CACHE("usrTkn",7*24*60*60),/***验证码缓存5分钟ttl*/SMS_CAPTCHA_CACHE("smsCode",5*60);/***缓存名称*/privatefinalStringcacheName;/***缓存过期秒数*/privatefinalintttlSecond;CacheEnum(StringcacheName,intttlSecond){this.cacheName=cacheName;this.ttlSecond=ttlSecond;}publicStringcacheName(){returnthis.cacheName;}publicintttlSecond(){returnthis.ttlSecond;}}这可以清楚地描述个性化缓存。然后我们通过将RedisCacheConfiguration和RedisCacheManagerBuilderCustomizer分别注入SpringIoC来个性化配置。可以关注CacheEnum的工作原理。如果你有其他个性化需求,也可以自定义这两个配置类。importcn.felord.kono.enumeration.CacheEnum;importorg.springframework.boot.autoconfigure.cache.CacheProperties;importorg.springframework.boot.autoconfigure.cache.RedisCacheManagerBuilderCustomizer;importorg.springframework.cache.annotation.EnableCaching;importorg.springframework.context。annotation.Bean;importorg.springframework.context.annotation.Configuration;importorg.springframework.data.redis.cache.RedisCacheConfiguration;importorg.springframework.data.redis.cache.RedisCacheManager;importorg.springframework.data.redis.core.RedisTemplate;importorg.springframework.data.redis.serializer.RedisSerializationContext;importjava.time.Duration;importjava.util.EnumSet;importjava.util.stream.Collectors;/***redis绑定保存.**@authorfelord.cn*@since2020/8/1720:14*/@EnableCaching@ConfigurationpublicclassCacheConfiguration{/***Rediscacheconfiguration.**@paramredisTemplatetheredistemplate*@returntherediscacheconfiguration*/@BeanpublicRedisCacheConfigurationredisCacheConfiguration(RedisTemplateredisTemplate,CachePropertiescacheProperties){//参见spring.cache.redisCacheProperties.RedisredisProperties=cacheProperties.getRedis();RedisCacheConfigurationredisCacheConfiguration=RedisCacheConfiguration.defaultCacheConfig()//绑定的序列化问题.serialize.SerializationSerializationPin.fromSerializer(redisTemplate.getValueSerializer()));if(redisProperties.getTimeToLive()!=null){//全局TTL时间=null){//键前缀值redisCacheConfiguration=redisCacheConfiguration.prefixCacheNameWith(redisProperties.getKeyPrefix());}if(!redisProperties.isCacheNullValues()){//默认缓存空值可以防止缓存穿透redisCacheConfiguration=redisCacheConfiguration.disableCachingNullValues();}if(!redisProperties.isUseKeyPrefix()){//不使用键前缀redisCacheConfiguration=redisCacheConfiguration。disableKeyPrefix();}returnredisCacheConfiguration;}/***Rediscachemanager个性化配置缓存过期时间.*@seeRedisCacheManager,CacheEnum*@returntherediscachemanagerbuildercustomizer*/@BeanpublicRedisCacheManagerBuilderCustomizerredisCacheManagerBuilderCustomizer(RedisCacheConfigurationredisCacheConfiguration){returnbuilder->builder.cacheDefaults(redisCacheConfiguration)//自定义的一些缓存配置初始化主要是具体的缓存和它的ttl时间))))));}}在个性化的同时,我们可以通过@EnableCaching开启SpringCache缓存支持。关于SpringCache的详细内容可以通过《SpringCache详解》一文了解。验证SpringCacheRedis缓存个性化请注意,只有通过SpringCache对缓存进行操作才能达到上图的效果。命令行操作需要显式声明指令。7.总结一下,最近事情比较多,难得抽出时间去做。如果在实际开发中遇到需要集成的功能,也可以告诉我。同时,如果您在集成中发现了一些缺陷或bug,请提交一个ISSUE。多多关注:码农小胖哥,跟我一起集成开发脚手架。本文转载自微信公众号“码农小胖哥”,可通过以下二维码关注。转载本文请联系码农小胖公众号。码农胖哥