自拍偷在线精品自拍偷,亚洲欧美中文日韩v在线观看不卡

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

開發(fā) 架構(gòu)
Spring 框架從 3.1 開始,對 Spring 應(yīng)用程序提供了透明式添加緩存的支持。和事務(wù)支持一樣,抽象緩存允許一致地使用各種緩存解決方案,并對代碼的影響最小。

環(huán)境:springboot2.3.12.RELEASE + JSR107 + Ehcache + JPA

Spring 框架從 3.1 開始,對 Spring 應(yīng)用程序提供了透明式添加緩存的支持。和事務(wù)支持一樣,抽象緩存允許一致地使用各種緩存解決方案,并對代碼的影響最小。從 Spring4.1 版本開始,緩存抽象支持了 JSR-107 注釋和更多自定義選項,從而得到了顯著的改進。

方式1:直接使用spring的注解來實現(xiàn)緩存

spring提供了如下注解:

@Cacheable 觸發(fā)緩存機制

@CacheEvict 觸發(fā)緩存回收

@CachePut 更新緩存,而不會影響方法的執(zhí)行

@Caching 組合多個緩存操作到一個方法

@CacheConfig 類級別共享系誒常見的緩存相關(guān)配置

<dependency>
  <groupId>org.springframework.boot</groupId>
  <artifactId>spring-boot-starter-cache</artifactId>
</dependency>

首先在Service對應(yīng)的方法是添加注解:

@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語句:

圖片圖片

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

注意在這些注釋中我們是可以使用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 說明是要緩存的參數(shù)值。
  @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 必須全部用同一個,
// 跟蹤了下源碼是用的對應(yīng)的類名key來查找對應(yīng)的緩存的;一開始我沒有用同一個始終不正確。。
// 看下圖跟蹤的代碼:

圖片圖片

這里必須要一樣哦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>

測試增刪改:

先添加個數(shù)據(jù):

圖片圖片

圖片圖片

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

圖片圖片

圖片圖片

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

接著做刪除操作:

圖片圖片

圖片圖片

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

圖片圖片

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

責任編輯:武曉燕 來源: 實戰(zhàn)案例錦集
相關(guān)推薦

2021-09-27 08:16:38

Webpack 前端Cache

2023-03-30 07:48:46

接口鑒權(quán)SpringBoot

2009-08-05 15:13:32

使用Cache提高AS

2018-06-22 13:45:08

數(shù)據(jù)庫MySQLtable-cache

2020-11-04 18:13:24

DebianUbuntuapt-cache命令

2020-06-04 16:57:07

移動開發(fā)互聯(lián)網(wǎng)實踐

2022-05-17 08:25:10

TypeScript接口前端

2024-08-01 08:06:11

虛擬線程性能

2018-10-24 10:45:15

云盤云服務(wù)存儲

2011-09-16 10:19:41

2009-06-05 15:04:36

Eclipse代碼模版

2023-10-19 13:56:00

Vue項目Mock.js

2020-07-22 08:30:02

代碼開發(fā)工具

2012-04-23 10:30:38

Hadoop

2011-06-28 10:03:37

Qt OpenCV qmake

2011-06-30 10:50:39

Qt OpenCV

2017-03-13 09:50:00

HadoopHive

2023-05-12 13:21:12

JMHJava程序

2023-03-01 15:14:48

數(shù)據(jù)集機器學習

2024-05-11 08:47:36

Python工具裝飾器
點贊
收藏

51CTO技術(shù)棧公眾號