亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb

首頁 > 開發 > Java > 正文

Spring Boot 中使用cache緩存的方法

2024-07-13 10:16:45
字體:
來源:轉載
供稿:網友

一、什么是緩存 Cache

Cache 一詞最早來自于CPU設計

當CPU要讀取一個數據時,首先從CPU緩存中查找,找到就立即讀取并送給CPU處理;沒有找到,就從速率相對較慢的內存中讀取并送給CPU處理,同時把這個數據所在的數據塊調入緩存中,可以使得以后對整塊數據的讀取都從緩存中進行,不必再調用內存。正是這樣的讀取機制使CPU讀取緩存的命中率非常高(大多數CPU可達90%左右),也就是說CPU下一次要讀取的數據90%都在CPU緩存中,只有大約10%需要從內存讀取。這大大節省了CPU直接讀取內存的時間,也使CPU讀取數據時基本無需等待??偟膩碚f,CPU讀取數據的順序是先緩存后內存。

再到后來,出先了硬盤緩存,然后到應用緩存,瀏覽器緩存,Web緩存,等等!

緩存為王??!

Spring Cache

Spring Cache是Spring針對Spring應用,給出的一整套應用緩存解決方案。

Spring Cache本身并不提供緩存實現,而是通過統一的接口和代碼規范,配置、注解等使你可以在Spring應用中使用各種Cache,而不用太關心Cache的細節。通過Spring Cache ,你可以方便的使用

各種緩存實現,包括ConcurrentMap,Ehcache 2.x,JCache,Redis等。

Spring中Cache的定義

Sping 中關于緩存的定義,包括在接口 org.springframework.cache.Cache 中,

它主要提供了如下方法

// 根據指定key獲取值<T> T get(Object key, Class<T> type)// 將指定的值,根據相應的key,保存到緩存中void put(Object key, Object value);// 根據鍵,回收指定的值void evict(Object key)

從定義中不難看著,Cache 事實上就是一個key-value的結構,我們通過個指定的key來操作相應的value

Cache Manager

Cache是key-value的集合,但我們在項目中,可能會存在各種業務主題的不同的Cache,比如用戶的cache,部門的Cache等,這些cache在邏輯上是分開的。為了區分這些Cache,提供了org.springframework.cache.CacheManager用來管理各種Cache.該接口只包含兩個方法

// 根據名字獲取對應主題的緩存Cache getCache(String name);// 獲取所有主題的緩存Collection<String> getCacheNames();

在該接口中,不允許對Cache進行增加、刪除操作,這些操作應該在各種CacheManager實現的內部完成,而不應該公開出來。

基于注解的緩存

對數據的緩存操作,理論上和業務本身的相關性不大,我們應當把對Cache的讀寫操作從主要代碼邏輯中分離出來。Spring分離的方式就是基于注解的(當然像JSR-107等也是基于注解的)。

Spring 提供了一系列的注解,包括@Cacheable,@CachePut,@CacheEvict等一系列注解來簡化我們對緩存的操做,這些注解都位于org.springframework.cache.annotation包下。

二、例子

一個簡單的Spring Boot使用Spring Cache的例子

我們一步一步,來構建一個基于Spring Boot Cache的例子

新建一個Spring Boot 項目,引入如下依賴

<dependencies>  <dependency>    <groupId>org.springframework.boot</groupId>    <artifactId>spring-boot-starter-cache</artifactId>  </dependency>  <dependency>    <groupId>org.springframework.boot</groupId>    <artifactId>spring-boot-starter-web</artifactId>  </dependency>  <dependency>    <groupId>org.springframework.boot</groupId>    <artifactId>spring-boot-starter-test</artifactId>    <scope>test</scope>  </dependency></dependencies>

其中,spring-boot-starter-cache是cache關鍵依賴。

修改Application類,加入啟用緩存的注解@EnableCaching

@SpringBootApplication@EnableCachingpublic class CacheSimpleApplication {  public static void main(String[] args) {    SpringApplication.run(CacheSimpleApplication.class, args);  }}

@EnableCache注解啟動了Spring的緩存機制,它會使應用檢測所有緩存相關的注解并開始工作,同時還會創建一個CacheManager的bean,可以被我們的應用注入使用。

新建一個RestController類

@RestController@RequestMapping("/")public class CacheController {  @Autowired  private CacheTestService cacheTestService;  /**   * 根據ID獲取信息   *    * @param id   * @return   */  @GetMapping("{id}")  public String test(@PathVariable("id") String id) {    return cacheTestService.get(id);  }  /**   * 刪除某個ID的信息   *    * @param id   * @return   */  @DeleteMapping("{id}")  public String delete(@PathVariable("id") String id) {    return cacheTestService.delete(id);  }  /**   * 保存某個ID的信息   *    * @param id   * @return   */  @PostMapping  public String save(@RequestParam("id") String id, @RequestParam("value") String value) {    return cacheTestService.save(id, value);  }  /**   * 跟新某個ID的信息   *    * @param id   * @return   */  @PutMapping("{id}")  public String update(@PathVariable("id") String id, @RequestParam("value") String value) {    return cacheTestService.update(id, value);  }}

該類調用某個Service來實現實際的增刪改查操作。

Service 實現

接下來,我們要實現我們的Service

@Servicepublic class SimpleCacheTestServiceImpl implements CacheTestService {  private static final Logger logger = LoggerFactory.getLogger(SimpleCacheTestServiceImpl.class);  private final Map<String, String> enties = new HashMap<>();  public SimpleCacheTestServiceImpl() {    enties.put("1", "this no 1");  }  @Autowired  private CacheManager cacheManager;  @Override  @Cacheable(cacheNames = "test")  public String get(String id) {    // 記錄數據產生的時間,用于測試對比    long time = new Date().getTime();    // 打印使用到的cacheManager    logger.info("The cacheManager is" + cacheManager);    // 當數據不是從cache里面獲取時,打印日志    logger.info("Get value by id=" + id + ", The time is " + time);    return "Get value by id=" + id + ",the value is" + enties.get(id);  }  @Override  public String delete(String id) {    return enties.remove(id);  }  @Override  public String save(String id, String value) {        logger.info("save value " + value + " with key " + id);    enties.put(id, value);    return value;  }  @Override  public String update(String id, String value) {    return enties.put(id, value);  }}

緩存

首先在get方法上加上 @Cacheable 注解,運行代碼測試。

我們使用postman做測試,測試地址為 http://localhost:8080/1 ,瀏覽器響應Get value by id=1,the value isthis no 1,服務器控制臺打印兩行日志

Get value by id=1,the value isthis no 1 Get value by id=1, The time is 1516004770216 

但我們再次刷新瀏覽器地址時,瀏覽器正常返回,但控制臺已經不再打印了,原因是第二次調用時,Spring 已經不再執行方法,而是直接獲取緩存的值。 Spring Cache將函數的返回值以函數參數為key,緩存在了名為test的緩存中 。

這里我們使用了 @Cacheable 注解,注解中的cacheNames指定了這里讀取的是哪個Cache。這里會在cacheName="test"的cache中去查找key是id的緩存對象。

刪除緩存中的數據

在上面的程序中,如果我們通過delete請求刪除指定值,發送delete請求到 http://localhost:8080/1 ,這個時候,值已經從map中刪除了,但我們get 請求到 http://localhost:8080/1 的時候,仍然可以拿到值,這是因為我們在刪除數據的時候,沒有刪除緩存中的數據,而在前面的get方法中,方法的運行結果仍然被保存著,Spring不會去重新讀取,而是直接讀取緩存。這個時候,我們在方法前面加上注解

@Override@CacheEvict(cacheNames = "test")public String delete(String id) {  return enties.remove(id);}

先后測試,首先調用get請求,會正確顯示返回值為Get value by id=1,the value is 1

然后調用delete請求。將數據從cache和map中刪除,再次調用get請求,這時返回Get value by id=1,the value is null,代表該值確實從緩存中刪除了。

這里我們使用了 @CacheEvict 注解,cacheNames指定了刪除哪個cache中的數據, 默認會使用方法的參數作為刪除的key

更新緩存

當程序到這里時,如果我們運行post請求,請求體為 id=1&value=new1,這時控制臺打印save value new value1 with key 1,代碼會將值保存到map中,但我們運行get請求時,會發現返回值仍然是之前的狀態。這是我們可以使用

@Override@CachePut(cacheNames = "test", key = "#id")public String save(String id, String value) {  logger.info("save value " + value + " with key " + id);  return enties.put(id, value);}

重新執行代碼,我們先發送delete請求,從map和和cache中刪除數據。然后再發送post請求,寫入數據到map中。最后再發送get請求,會發現現在可以正確的取到值了,控制臺也沒有打印從map中獲取數據的日志。

這里用到了 @CachePut 注解,這個注解的作用是 將方法的返回值按照給定的key,寫入到cacheNames指定的cache中去 。

同樣,我們需要再put方法上加上 @CachePut 注解,讓修改也能刷新緩存中的數據。

到這里,一個簡單的包含增刪改查的緩存應用就完成了。

三、劃重點

幾個注解

  • @EnableCaching 啟用緩存配置
  • @Cacheable 指定某個方法的返回值是可以緩存的。在注解屬性中指定緩存規則。
  • @Cacheput 將方法的返回值緩存到指定的key中
  • @CacheEvict 刪除指定的緩存數據

注意

@Cacheable和@Cacheput都會將方法的執行結果按指定的key放到緩存中,@Cacheable在執行時,會先檢測緩存中是否有數據存在,如果有,直接從緩存中讀取。如果沒有,執行方法,將返回值放入緩存,而@Cacheput會先執行方法,然后再將執行結果寫入緩存。 使用@Cacheput的方法一定會執行

完整的示例代碼在 https://github.com/ldwqh0/cache-test

總結

以上所述是小編給大家介紹的Spring Boot 中使用cache緩存的方法,希望對大家有所幫助,如果大家有任何疑問請給我留言,小編會及時回復大家的。在此也非常感謝大家對VeVb武林網網站的支持!


注:相關教程知識閱讀請移步到JAVA教程頻道。
發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb
77777亚洲午夜久久多人| 日本91av在线播放| 国产欧美日韩免费看aⅴ视频| 92福利视频午夜1000合集在线观看| 中文字幕免费精品一区高清| 岛国精品视频在线播放| 国产精品久久久久不卡| 日韩亚洲欧美中文在线| zzijzzij亚洲日本成熟少妇| 欧洲精品久久久| 91久久久久久久久久| 国产精自产拍久久久久久| 5252色成人免费视频| 欧美日韩在线看| 77777少妇光屁股久久一区| 国产精品av网站| 国产精国产精品| 深夜福利亚洲导航| 91久久精品国产91久久| 中文字幕在线看视频国产欧美在线看完整| 国产精品激情av电影在线观看| 国产不卡在线观看| 一本色道久久88亚洲综合88| 亚洲国产日韩欧美在线图片| 国产精品入口尤物| 国产xxx69麻豆国语对白| 国产精品极品美女粉嫩高清在线| 91在线观看免费高清完整版在线观看| 欧美日韩国产黄| 国产成人在线亚洲欧美| 国产精品香蕉国产| 亚洲经典中文字幕| 91国内在线视频| 精品亚洲一区二区三区| 日韩精品亚洲精品| 亚洲欧美在线免费观看| 久久久久久久网站| 丝袜美腿亚洲一区二区| 国产成人欧美在线观看| 91精品综合久久久久久五月天| 国产精品免费一区豆花| 国产精品亚洲视频在线观看| 中文在线不卡视频| 亚洲成人中文字幕| 97精品在线视频| 中文字幕在线看视频国产欧美在线看完整| 欧美性生交大片免费| 国产精品旅馆在线| 欧美亚洲第一区| 97成人精品区在线播放| 日韩av不卡在线| 欧美午夜激情小视频| 国产精品福利无圣光在线一区| 美女视频黄免费的亚洲男人天堂| 亚洲欧洲国产伦综合| 欧美日韩一区免费| 久久人人爽人人爽爽久久| 日韩av免费看网站| 一本一本久久a久久精品牛牛影视| 国产精品久久久久久久9999| 久久综合九色九九| 欧美成人精品激情在线观看| 日本久久久久久久久| 成人福利在线观看| 国产精品久久久久久婷婷天堂| 日韩精品在线影院| 亚洲精品久久久久中文字幕二区| 亚洲国产精品久久久久久| 一本色道久久综合狠狠躁篇怎么玩| 久久精品成人动漫| 精品一区二区三区四区在线| 国产精品www| 亚洲成av人片在线观看香蕉| 欧美日本精品在线| 欧美一区二区三区四区在线| 一本色道久久综合亚洲精品小说| 成人黄色在线观看| 2023亚洲男人天堂| 97av在线影院| xvideos亚洲人网站| 日韩av电影在线播放| 国产经典一区二区| 久久久国产精品免费| 欧美在线视频观看免费网站| 91在线观看免费高清完整版在线观看| 中文字幕国内精品| 性色av一区二区咪爱| 国产丝袜视频一区| 91精品国产高清久久久久久91| 奇米影视亚洲狠狠色| 亚洲欧美综合区自拍另类| 亚洲福利在线播放| 亚洲美女av网站| 亚洲第一免费网站| 国内精品一区二区三区| 国产精品小说在线| 亚洲性av网站| 亚洲精品久久久久中文字幕二区| 欧美精品一二区| 国产伦精品免费视频| 91亚洲精品一区| 久久成人这里只有精品| 136fldh精品导航福利| 日韩大陆欧美高清视频区| 欧美精品电影在线| 欧美福利在线观看| 日韩中文字幕在线看| 九九久久综合网站| 国产精品免费视频久久久| 亚洲sss综合天堂久久| 中文一区二区视频| 欧美在线视频一区二区| 国产精品成人品| 日本久久久久亚洲中字幕| 亚洲黄色av网站| 精品久久久一区二区| 亚洲精品天天看| 成人免费视频97| 成人精品一区二区三区电影黑人| 狠狠色噜噜狠狠狠狠97| 精品国产乱码久久久久酒店| 欧洲成人在线观看| 欧美日韩国产成人高清视频| 日韩免费观看视频| 中文字幕日韩免费视频| 美女视频黄免费的亚洲男人天堂| 狠狠躁天天躁日日躁欧美| 亚洲国产精品va在线| 精品视频在线播放免| 亚洲欧美中文日韩v在线观看| 欧美日韩第一视频| 日韩精品免费一线在线观看| 精品久久香蕉国产线看观看亚洲| 成人在线激情视频| 最近2019免费中文字幕视频三| 欧美激情免费观看| 中文字幕亚洲情99在线| 亚洲激情久久久| 日韩中文理论片| 欧美极品少妇xxxxⅹ免费视频| 国产亚洲精品一区二区| 日韩欧美在线视频免费观看| 97超碰蝌蚪网人人做人人爽| 91成人国产在线观看| 国产在线不卡精品| 黄网站色欧美视频| 日韩在线视频观看| 国产亚洲xxx| 久久人人爽人人爽人人片亚洲| 91亚洲国产成人精品性色| 伊人久久久久久久久久| 国模精品系列视频| 亚洲一区二区三区sesese| 69久久夜色精品国产69乱青草| 57pao国产成人免费| 日韩欧美在线视频观看| 成人免费黄色网| 久久青草精品视频免费观看| 欧美精品激情blacked18| 91天堂在线视频| 亚洲视频在线观看免费| 欧美高清激情视频| 欧美日韩激情美女| 欧美国产日韩中文字幕在线|