成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

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對應的方法是添加注解:

@Service
public class StorageService {
  
  @Resource
  private StorageRepository sr ;
  
  @Cacheable(value = {"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 String  KEY_PREFIX = "storage_" ;
  
  @Override
  public 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 {
  
  @Resource
  private StorageService storageService ;


  @GetMapping("/{id}")
  public Object get(@PathVariable("id") Long id) {
    return storageService.getStorage(id) ;
  }
}

測試:

第一次訪問接口,查看控制臺輸出了sql語句:

圖片圖片

再次訪問接口,發現控制臺沒有再輸出任何sql,說明我們的緩存生效了(這里你也可以把這里的注解注釋了來看效果)。關于這里的更新緩存,刪除緩存就不演示了。接下來完整的演示下JSR107規范中的注解演示:

注意在這些注釋中我們是可以使用SpEL表達式的:

圖片圖片

方式2:使用JSR107和Ehcache

先來看看Spring與JSR107注解的對照表:

圖片圖片

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類:

@Service
public class StorageService {
  
  @Resource
  private 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來查找對應的緩存的;一開始我沒有用同一個始終不正確。。
// 看下圖跟蹤的代碼:

圖片圖片

這里必須要一樣哦cacheKeyGenerator

緩存Key:JCacheKeyGenerator.java

public class JCacheKeyGenerator implements CacheKeyGenerator {


  private static final String  KEY_PREFIX = "storage_" ;
  
  @Override
  public GeneratedCacheKey generateCacheKey(
      CacheKeyInvocationContext<? extends Annotation> cacheKeyInvocationContext) {
    CacheInvocationParameter[] params = cacheKeyInvocationContext.getAllParameters() ;
    StringBuilder sb = new StringBuilder() ;
    for (CacheInvocationParameter param : params) {
      if (param.getValue() instanceof Storage) {
        Storage s = (Storage) param.getValue() ;
        sb.append(s.getId()) ;
      } else {
        sb.append((Long)param.getValue()) ;
      }
    }
    return new StorageGeneratedCacheKey(KEY_PREFIX + sb.toString()) ;
  }
  
  private static class StorageGeneratedCacheKey implements GeneratedCacheKey {
    private static final long serialVersionUID = 1L;
    
    private String key ;
    
    public StorageGeneratedCacheKey(String key) {
      this.key = key ;
    }


    @Override
    public int hashCode() {
      final int prime = 31;
      int result = 1;
      result = prime * result + ((key == null) ? 0 : key.hashCode());
      return result;
    }


    @Override
    public boolean equals(Object obj) {
      if (this == obj)
        return true;
      if (obj == null)
        return false;
      if (getClass() != obj.getClass())
        return false;
      StorageGeneratedCacheKey other = (StorageGeneratedCacheKey) obj;
      if (key == null) {
        if (other.key != null)
          return false;
        } else if (!key.equals(other.key))
          return false;
      return true;
      }
    
    }


}

application.yml配置:

spring:
  cache:
    cacheNames:
    - cache_storage
    ehcache:
      config: classpath:ehcache.xml

ehcache.xml

<?xml versinotallow="1.0" encoding="UTF-8"?>
<ehcache xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:noNamespaceSchemaLocation="http://ehcache.org/ehcache.xsd"
         updateCheck="false">


  <diskStore path="java.io.tmpdir/Tmp_EhCache"/>
   
  <defaultCache eternal="false" maxElementsInMemory="10000"  overflowToDisk="false" diskPersistent="false" timeToIdleSeconds="1800" timeToLiveSeconds="259200" memoryStoreEvictionPolicy="LRU" />


  <cache name="cache_storage" eternal="false" maxElementsInMemory="5000"  overflowToDisk="false" diskPersistent="false" timeToIdleSeconds="1800" timeToLiveSeconds="1800" memoryStoreEvictionPolicy="LRU" />
 
</ehcache>

測試增刪改:

先添加個數據:

圖片圖片

圖片圖片

成功添加ID為4的信息,Service中的save方法中我們添加了@CachePut注解,接下來我們查詢ID為4的信息,看看控制臺是否會生成SQL語句。

圖片圖片

圖片圖片

控制臺沒有增加任何的SQL語句,說明save方法加的@CachePut生效了。

接著做刪除操作:

圖片圖片

圖片圖片

ID為4的刪除了,接下來再做查詢看看:

圖片圖片

這說明刪除了數據后,緩存也做了刪除。這里生成了查詢語句。

責任編輯:武曉燕 來源: 實戰案例錦集
相關推薦

2021-09-27 08:16:38

Webpack 前端Cache

2025-06-18 11:16:50

大模型性能KV-Cache

2023-03-30 07:48:46

接口鑒權SpringBoot

2009-08-05 15:13:32

使用Cache提高AS

2020-06-04 16:57:07

移動開發互聯網實踐

2011-09-16 10:19:41

2018-10-24 10:45:15

云盤云服務存儲

2018-06-22 13:45:08

數據庫MySQLtable-cache

2020-11-04 18:13:24

DebianUbuntuapt-cache命令

2022-05-17 08:25:10

TypeScript接口前端

2009-06-05 15:04:36

Eclipse代碼模版

2024-08-01 08:06:11

虛擬線程性能

2023-03-01 15:14:48

數據集機器學習

2020-07-22 08:30:02

代碼開發工具

2023-10-19 13:56:00

Vue項目Mock.js

2023-05-12 13:21:12

JMHJava程序

2017-03-13 09:50:00

HadoopHive

2011-06-28 10:03:37

Qt OpenCV qmake

2012-04-23 10:30:38

Hadoop

2011-06-30 10:50:39

Qt OpenCV
點贊
收藏

51CTO技術棧公眾號

主站蜘蛛池模板: 日本一区二区三区免费观看 | 国产成人精品一区二 | 欧美日韩视频在线播放 | 精品国产一级 | 麻豆视频国产在线观看 | 成人精品福利 | 99热欧美 | 黄色一级大片在线免费看产 | 婷婷久久久久 | 亚洲精品视频免费 | 男人天堂网站 | 国产91在线播放精品91 | 日本成人片在线观看 | 日本又色又爽又黄的大片 | 毛片网站在线观看 | 一本色道精品久久一区二区三区 | 精品一区二区三区在线观看国产 | 操视频网站 | 午夜a级理论片915影院 | 久久国产精99精产国高潮 | 成人免费观看男女羞羞视频 | 亚洲国产一区在线 | 国产精品久久久久久久久久久久冷 | 国产精品久久久久无码av | 欧美视频在线观看 | 91视频一区二区 | 午夜免费小视频 | av国产精品 | 精品欧美乱码久久久久久 | 天天干天天插天天 | 中文字幕 在线观看 | 日本午夜精品 | 国产高清精品在线 | 成人免费观看视频 | 国产精品美女久久久久久免费 | 精品伊人久久 | 国产综合视频 | 国产一区三区在线 | 网站黄色在线 | 亚洲精品国产精品国自产在线 | 日本在线一二 |