SpringCache整合Redis做缓存使用~快速上手~
SpringCache通过集成Redis作为缓存工具来简化缓存管理。它是通过注解实现的,有优点也有缺点。
为了快速上手并使用SpringBoot,首先要进行常规的前期准备工作,例如引入SpringCache集成Redis依赖、配置相关配置文件和Redis配置等。
它直接应用于控制器、服务和映射器层之间,并且允许您在数据从服务层返回时缓存数据(如果您需要测试它)。
作为参考,这里有两种清除缓存的方法。
一种是擦除整个分区,另一种是针对特定键。
SpringCache注解要求方法是public的,@Cacheable用于缓存方法返回值,@CachePut用于更新缓存,@CacheEvict用于驱逐缓存。
@Caching提供了一组可以同时操作多个缓存的注解,@CacheConfig用于类级别的缓存配置,解决重复注解的问题。
需要记住的事情包括避免缓存分页查询结果、处理基于代理的AOP问题、确保@Cache注解的方法是公共的,以及理解@CacheEvict在发生异常时默认不会清除缓存。
深入理解这些特点还需要更多的实践和探索。
人人都要知道的,Redis缓存使用的三种模式
缓存技术在互联网应用中发挥着重要作用,其目的是提高系统性能和稳定性。Redis作为高性能缓存数据库,广泛应用于各种互联网场景。
本文重点介绍Redis缓存使用的三种模式:CacheAside(缓存旁路)、Read/Write(读写黑客)、WriteBehindCaching(异步缓存写入),并分析它们的特点和适用场景。
CacheAsideCacheAside模式是最直接的缓存方法。
应用程序首先尝试从缓存中读取数据,如果不存在,则从数据库中获取并临时存储。
更新过程中,先更新数据库,然后清除缓存。
该模式实现简单,缓存与数据库之间数据一致性好,适合读多写少、数据一致性要求不高的场景。
读/写/读/写模式通过中间层管理缓存与数据库的交互,提高并发性和扩展性。
应用程序通过中间层对缓存和数据库进行读写,保证数据的一致性。
适用于读写操作较多、数据一致性要求较高的场景。
WriteBehindCachingWriteBehindCaching模式先将操作记录在缓存中,然后异步更新数据库,有效提高写入性能,减轻数据库负担。
但要注意数据一致性问题。
该模式适用于写多读少、数据一致性要求不高的场景。
总结:Redis缓存模式的选择要根据具体的业务场景和需求而定。
CacheAside模式操作简单,适用于读写量大、数据一致性要求不高的情况;读写模式通过中间层将缓存和数据库分开,适用于需要大量读写、对数据一致性要求较高的情况。
场景:WriteBehindCaching模式通过异步写入提高写操作的性能,并且方便针对写多读少、数据一致性要求不高的场景。
在实际应用中,合理选择缓存模式可以极大地提高系统性能和稳定性。
SpringBoot整合Redis做缓存-自定义缓存序列化方式,防止缓存数据乱码问题
首先,添加依赖项:
我这里使用的SpringBoot版本是:2.2.5。
RELEASE
1.Jedis:
在实现上,它是直接连接到Redisserver的,不是多线程环境,除非使用连接池为每个redis实例添加物理连接。
2.Lettuce:
它是一个可扩展、安全且完全非阻塞的Redis客户端,多个线程可以共享一个RedisConnection。
它使用NettyNIO框架有效地管理多个连接,提供异步和同步数据访问以创建非阻塞交互式应用程序。
我的项目这里的配置文件使用的是Lettuce。
配置文件:
首先查找redis配置类,如果没有有超时,有新的配置类:
packagegc.cnnvd.config;importcom.fasterxml.jackson.annotation.JsonAutoDetect;importcom.fasterxml.jackson.annotation.PropertyAccessor;importcom.fasterxml.jackson.databind.ObjectMapper;导入org.springframework.context.annotation.Bean;导入org.springframework.context.annotation.Configuration;导入org.springframework.data.redis.connection.RedisConnectionFactory;importorg.springframework.data.redis.core.RedisTemplate;importorg.springframework.data.redis.serializer.Jackson2JsonRedisSerializer;importorg.springframework.data.redis.serializer.StringRedisSerializer;/****配置RedisTemplate*
**@authorlinmengmeng*@date2021-07-21*/@ConfigurationpublicclassRedisTemplateConfig{/***redisTemplate的配置*@paramfactory*@return***自定义RedisTemplate原因:*1.将public方法修改为*2.将值序列化方法更改为Jackson2JsonRedisSerializer,因为底层RedisSerializer不会将带双引号的值序列化为字符串类型,并且会自动添加双引号。
**/@Bean@Suppre ssWarnings("all")publicRedisTemplate
如果之前配置过redisTemplate,再次启动配置文件时会提示异常,提示redisTemplatebean创建失败,或者已经存在或者像那样的东西。
然后是RedisCacheConfig:
packagegc.cnnvd.config;importorg.springframework.cache.CacheManager;importorg.springframework.cache.annotation.CachingConfigurerSupport;importorg.springframework.cache.annotation.EnableCaching;importorg.springframework.cache.interceptor.KeyGenerator;importorg.springframework.context.annotation.Bean;importorg.springframework.context.annotation.Configuration;importorg.springframework.data.redis.cache.RedisCacheConfiguration;导入org.springframework.data.redis.cache.RedisCacheManager;导入org.springframework.data.redis.connection.RedisConnectionFactory;导入org.springframework.data.redis.serializer.Jackson2JsonRedisSerializer;importorg.springframework.data.redis.serializer.RedisSerializationContext;importorg.springframework.data.redis.serializer.RedisSerializer;importorg.springFramework.data.redis.serializer.StringRedisSerializer;importjava.time.Duration;importjava.util.Arrays;/****RedisCache配置*
*@authorgeekidea*@date2018-11-08*/@config@EnableCachingpublicclassRedisCacheConfigextendsCachingConfigurerSupport{@Bean@OverridepublicKeyGeneratorkeyGenerator(){return(目标、方法、参数)->{StringBufferredisKey=newStringBuffer();redisKey.append(target.getClass().getName())。追加(“-”);redisKey.append(method.getName());if(params.length>0){redisKey.append(“-”).append(Arrays.deepToString(params));}returnredisKey.toString();};}/***配置redis缓存*修改序列化方法,解决乱码缓存代码*@paramfactory*@return*/@BeanpublicCacheManagerrcacheManager(RedisConnectionFactoryfactory){RedisSerializer
我已将@EnableScheduling注释直接添加到此处的配置文件中。
如果这里不添加,可以直接在启动类中添加注解:@EnableScheduling
无论找到什么服务方法进行测试:
@Override@Cacheable(value="adminUser",key="#adminUserDetailParam获取我。d()",除非="#result==null")publicAdminUserDetailVOgetAdminUserDetail(AdminUserDetailParamadminUserDetailParam){AdminUserMergeradminUserMerger=adminUserMapper.selectAdminUserDetail(adminUserDetailParam.getId(),adminUserDetailParam.getVersion());log.info("------------转到数据库查询-------------");if(adminUserMerger==null){thrownewBusinessException("未找到用户信息");}AdminUserDetailVOadminUserDetailVO=newAdminUserDetailVO();BeanCopierUtils.copyProperties(adminUserMerger,adminUserDetailVO);returnadminUserDetailVO;
这里只有一行注解@Cacheable(value="adminUser",key="#adminUserDetailParam.getId()",unless="#result==null"),其中值是键前缀redis,导入com.alibaba.fastjson.JSONObject;导入gc.cnnvd.system.adminuser.param.AdminUserDetailParam;导入gc.cnnvd.system.adminuser.service.AdminUserService;导入gc.cnnvd.system。
管理员用户.vo.AdminUserDetailVO;importgc.cnnvd.test.BaseTest;importorg.junit.Test;importorg.springframework.beans.factory.annotation.Autowired;/***@Autherlinmengmeng*@Date2021-07-2019:15*/publicclassQueryTestextendsBaseTest{@AutowiredprivateAdminUserServiceadminUserService;@TestpublicvoidtestGetAdminDetail(){AdminUserDetailParamadminUserDetailParam=newAdminUserDetailParam();adminUserDetailParam.setId("test001");adminUserDetailParam.setVersion(0);AdminUserDetailVOadminUserDetail=adminUserService.getAdminUserDetail(adminUserDetailParam);System.out.println(JSONObject.toJSONString(adminUserDetail));}
写完测试用例后,发现缓存第一次运行良好,执行了数据库查询。
第二次,直接进入redis缓存。
缓存,使用可视化工具显示如下图:
作者:linmengmengp>