SpringBoot中使用Cache提升接口性能详解

Spring 框架从 3.1 开始 , 对 Spring 应用程序提供了透明式添加缓存的支持 。和事务支持一样 , 抽象缓存允许一致地使用各种缓存解决方案 , 并对代码的影响最小 。环境:springboot2.3.12.RELEASE + JSR107 + Ehcache + JPA
Spring 框架从 3.1 开始 , 对 Spring 应用程序提供了透明式添加缓存的支持 。和事务支持一样 , 抽象缓存允许一致地使用各种缓存解决方案 , 并对代码的影响最小 。从 Spring4.1 版本开始 , 缓存抽象支持了 JSR-107 注释和更多自定义选项 , 从而得到了显著的改进 。
方式1:直接使用spring的注解来实现缓存
spring提供了如下注解:
@Cacheable 触发缓存机制
@CacheEvict 触发缓存回收
@CachePut 更新缓存 , 而不会影响方法的执行
@Caching 组合多个缓存操作到一个方法
@CacheConfig 类级别共享系诶常见的缓存相关配置
<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-cache</artifactId></dependency>首先在Service对应的方法是添加注解:
@Servicepublic class StorageService {@Resourceprivate StorageRepository sr ;@Cacheable(value = https://www.isolves.com/it/cxkf/kj/2023-08-03/{"cache_storage"}, keyGenerator = "storageKey")public Storage getStorage(Long id) {return sr.findById(id).get() ;}} // 这里的keyGenerator是你自定义Key生成的Bean名称@Component("storageKey")public class StorageKeyGenerator implements KeyGenerator {private static final StringKEY_PREFIX = "storage_" ;@Overridepublic Object generate(Object target, Method method, Object... params) {StringBuilder sb = new StringBuilder() ;for (Object param : params) {sb.Append(param) ;}return KEY_PREFIX + sb.toString() ;}}web接口:
@RestController@RequestMapping("/storages")public class StorageController {@Resourceprivate StorageService storageService ;@GetMapping("/{id}")public Object get(@PathVariable("id") Long id) {return storageService.getStorage(id) ;}}测试:
第一次访问接口 , 查看控制台输出了sql语句:
【SpringBoot中使用Cache提升接口性能详解】

SpringBoot中使用Cache提升接口性能详解

文章插图
图片
再次访问接口 , 发现控制台没有再输出任何sql , 说明我们的缓存生效了(这里你也可以把这里的注解注释了来看效果) 。关于这里的更新缓存 , 删除缓存就不演示了 。接下来完整的演示下JSR107规范中的注解演示:
注意在这些注释中我们是可以使用SpEL表达式的:
SpringBoot中使用Cache提升接口性能详解

文章插图
图片
方式2:使用JSR107和Ehcache
先来看看Spring与JSR107注解的对照表:
SpringBoot中使用Cache提升接口性能详解

文章插图
图片
pom.xml中加入依赖:
<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-cache</artifactId></dependency><dependency><groupId>MySQL</groupId><artifactId>mysql-connector-JAVA</artifactId></dependency><dependency><groupId>org.ehcache</groupId><artifactId>ehcache</artifactId></dependency><dependency><groupId>javax.cache</groupId><artifactId>cache-api</artifactId></dependency>Service类:
@Servicepublic class StorageService {@Resourceprivate StorageRepository sr ;// 这里的 @CacheValue 说明是要缓存的参数值 。@Transactional@CachePut(cacheName = "cache_storage", cacheKeyGenerator = JCacheKeyGenerator.class)public Storage save(@CacheValue Storage storage) {return sr.saveAndFlush(storage) ;}@CacheResult(cacheName = "cache_storage", cacheKeyGenerator = JCacheKeyGenerator.class)public Storage getStorage(Long id) {return sr.findById(id).get() ;}@Transactional@CacheRemove(cacheName = "cache_storage", cacheKeyGenerator = JCacheKeyGenerator.class)public void removeStorage(Long id) {sr.deleteById(id) ;}@Transactional@CachePut(cacheName = "cache_storage", cacheKeyGenerator = JCacheKeyGenerator.class)public Storage updateStorage(@CacheValue Storage storage) {return sr.saveAndFlush(storage) ;}}// 注意这里的cacheKeyGenerator 必须全部用同一个 , // 跟踪了下源码是用的对应的类名key来查找对应的缓存的;一开始我没有用同一个始终不正确 。。// 看下图跟踪的代码:
SpringBoot中使用Cache提升接口性能详解


推荐阅读