成人免费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

2009-06-05 15:04:36

Eclipse代碼模版

2022-05-17 08:25:10

TypeScript接口前端

2020-11-04 18:13:24

DebianUbuntuapt-cache命令

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

2024-11-06 09:26:48

SpringprofileENV

2012-04-23 10:30:38

Hadoop

2011-06-28 10:03:37

Qt OpenCV qmake
點贊
收藏

51CTO技術棧公眾號

主站蜘蛛池模板: 国产在线拍偷自揄拍视频 | 亚洲一区二区av | 九九亚洲 | 99av成人精品国语自产拍 | 夜夜草| 在线看91| 午夜影院视频 | 国产精品视频一区二区三区四区国 | 欧美日韩激情 | 黄页网址在线观看 | 国产一区2区 | 天堂资源最新在线 | 久久亚洲欧美日韩精品专区 | 亚洲精品久久区二区三区蜜桃臀 | 99久久精品免费看国产四区 | 国产精品毛片一区二区三区 | 久在线| 一区二区三区av | 福利网站导航 | a a毛片| 亚洲精品一区二区 | 午夜小视频在线观看 | 国产伦一区二区三区视频 | 高清视频一区 | 欧美激情va永久在线播放 | 免费高清av | 国产午夜精品久久久 | 黄网站涩免费蜜桃网站 | 中文二区 | 亚洲国产视频一区二区 | 91av在线影院| 羞羞视频在线观看 | 综合久久av | 午夜一区二区三区视频 | 亚洲成人动漫在线观看 | 日韩午夜激情 | 中文字幕亚洲一区 | 亚洲一区在线日韩在线深爱 | 国产精品久久久久久久久婷婷 | 亚洲欧洲视频 | 免费视频成人国产精品网站 |