欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

Spring Boot 中使用cache緩存的方法

 更新時(shí)間:2018年01月16日 09:19:36   作者:蝦游于海  
Spring Cache是Spring針對(duì)Spring應(yīng)用,給出的一整套應(yīng)用緩存解決方案。下面小編給大家?guī)?lái)了Spring Boot 中使用cache緩存的方法,感興趣的朋友參考下吧

一、什么是緩存 Cache

Cache 一詞最早來(lái)自于CPU設(shè)計(jì)

當(dāng)CPU要讀取一個(gè)數(shù)據(jù)時(shí),首先從CPU緩存中查找,找到就立即讀取并送給CPU處理;沒(méi)有找到,就從速率相對(duì)較慢的內(nèi)存中讀取并送給CPU處理,同時(shí)把這個(gè)數(shù)據(jù)所在的數(shù)據(jù)塊調(diào)入緩存中,可以使得以后對(duì)整塊數(shù)據(jù)的讀取都從緩存中進(jìn)行,不必再調(diào)用內(nèi)存。正是這樣的讀取機(jī)制使CPU讀取緩存的命中率非常高(大多數(shù)CPU可達(dá)90%左右),也就是說(shuō)CPU下一次要讀取的數(shù)據(jù)90%都在CPU緩存中,只有大約10%需要從內(nèi)存讀取。這大大節(jié)省了CPU直接讀取內(nèi)存的時(shí)間,也使CPU讀取數(shù)據(jù)時(shí)基本無(wú)需等待??偟膩?lái)說(shuō),CPU讀取數(shù)據(jù)的順序是先緩存后內(nèi)存。

再到后來(lái),出先了硬盤(pán)緩存,然后到應(yīng)用緩存,瀏覽器緩存,Web緩存,等等!

緩存為王??!

Spring Cache

Spring Cache是Spring針對(duì)Spring應(yīng)用,給出的一整套應(yīng)用緩存解決方案。

Spring Cache本身并不提供緩存實(shí)現(xiàn),而是通過(guò)統(tǒng)一的接口和代碼規(guī)范,配置、注解等使你可以在Spring應(yīng)用中使用各種Cache,而不用太關(guān)心Cache的細(xì)節(jié)。通過(guò)Spring Cache ,你可以方便的使用

各種緩存實(shí)現(xiàn),包括ConcurrentMap,Ehcache 2.x,JCache,Redis等。

Spring中Cache的定義

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

它主要提供了如下方法

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

從定義中不難看著,Cache 事實(shí)上就是一個(gè)key-value的結(jié)構(gòu),我們通過(guò)個(gè)指定的key來(lái)操作相應(yīng)的value

Cache Manager

Cache是key-value的集合,但我們?cè)陧?xiàng)目中,可能會(huì)存在各種業(yè)務(wù)主題的不同的Cache,比如用戶(hù)的cache,部門(mén)的Cache等,這些cache在邏輯上是分開(kāi)的。為了區(qū)分這些Cache,提供了org.springframework.cache.CacheManager用來(lái)管理各種Cache.該接口只包含兩個(gè)方法

// 根據(jù)名字獲取對(duì)應(yīng)主題的緩存
Cache getCache(String name);
// 獲取所有主題的緩存
Collection<String> getCacheNames();

在該接口中,不允許對(duì)Cache進(jìn)行增加、刪除操作,這些操作應(yīng)該在各種CacheManager實(shí)現(xiàn)的內(nèi)部完成,而不應(yīng)該公開(kāi)出來(lái)。

基于注解的緩存

對(duì)數(shù)據(jù)的緩存操作,理論上和業(yè)務(wù)本身的相關(guān)性不大,我們應(yīng)當(dāng)把對(duì)Cache的讀寫(xiě)操作從主要代碼邏輯中分離出來(lái)。Spring分離的方式就是基于注解的(當(dāng)然像JSR-107等也是基于注解的)。

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

二、例子

一個(gè)簡(jiǎn)單的Spring Boot使用Spring Cache的例子

我們一步一步,來(lái)構(gòu)建一個(gè)基于Spring Boot Cache的例子

新建一個(gè)Spring Boot 項(xiàng)目,引入如下依賴(lài)

<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關(guān)鍵依賴(lài)。

修改Application類(lèi),加入啟用緩存的注解@EnableCaching

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

@EnableCache注解啟動(dòng)了Spring的緩存機(jī)制,它會(huì)使應(yīng)用檢測(cè)所有緩存相關(guān)的注解并開(kāi)始工作,同時(shí)還會(huì)創(chuàng)建一個(gè)CacheManager的bean,可以被我們的應(yīng)用注入使用。

新建一個(gè)RestController類(lèi)

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

該類(lèi)調(diào)用某個(gè)Service來(lái)實(shí)現(xiàn)實(shí)際的增刪改查操作。

Service 實(shí)現(xiàn)

接下來(lái),我們要實(shí)現(xiàn)我們的Service

@Service
public 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) {
    // 記錄數(shù)據(jù)產(chǎn)生的時(shí)間,用于測(cè)試對(duì)比
    long time = new Date().getTime();
    // 打印使用到的cacheManager
    logger.info("The cacheManager is" + cacheManager);
    // 當(dāng)數(shù)據(jù)不是從cache里面獲取時(shí),打印日志
    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 注解,運(yùn)行代碼測(cè)試。

我們使用postman做測(cè)試,測(cè)試地址為 http://localhost:8080/1 ,瀏覽器響應(yīng)Get value by id=1,the value isthis no 1,服務(wù)器控制臺(tái)打印兩行日志

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

但我們?cè)俅嗡⑿聻g覽器地址時(shí),瀏覽器正常返回,但控制臺(tái)已經(jīng)不再打印了,原因是第二次調(diào)用時(shí),Spring 已經(jīng)不再執(zhí)行方法,而是直接獲取緩存的值。 Spring Cache將函數(shù)的返回值以函數(shù)參數(shù)為key,緩存在了名為test的緩存中 。

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

刪除緩存中的數(shù)據(jù)

在上面的程序中,如果我們通過(guò)delete請(qǐng)求刪除指定值,發(fā)送delete請(qǐng)求到 http://localhost:8080/1 ,這個(gè)時(shí)候,值已經(jīng)從map中刪除了,但我們get 請(qǐng)求到 http://localhost:8080/1 的時(shí)候,仍然可以拿到值,這是因?yàn)槲覀冊(cè)趧h除數(shù)據(jù)的時(shí)候,沒(méi)有刪除緩存中的數(shù)據(jù),而在前面的get方法中,方法的運(yùn)行結(jié)果仍然被保存著,Spring不會(huì)去重新讀取,而是直接讀取緩存。這個(gè)時(shí)候,我們?cè)诜椒ㄇ懊婕由献⒔?/p>

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

先后測(cè)試,首先調(diào)用get請(qǐng)求,會(huì)正確顯示返回值為Get value by id=1,the value is 1

然后調(diào)用delete請(qǐng)求。將數(shù)據(jù)從cache和map中刪除,再次調(diào)用get請(qǐng)求,這時(shí)返回Get value by id=1,the value is null,代表該值確實(shí)從緩存中刪除了。

這里我們使用了 @CacheEvict 注解,cacheNames指定了刪除哪個(gè)cache中的數(shù)據(jù), 默認(rèn)會(huì)使用方法的參數(shù)作為刪除的key

更新緩存

當(dāng)程序到這里時(shí),如果我們運(yùn)行post請(qǐng)求,請(qǐng)求體為 id=1&value=new1,這時(shí)控制臺(tái)打印save value new value1 with key 1,代碼會(huì)將值保存到map中,但我們運(yùn)行g(shù)et請(qǐng)求時(shí),會(huì)發(fā)現(xiàn)返回值仍然是之前的狀態(tài)。這是我們可以使用

@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);
}

重新執(zhí)行代碼,我們先發(fā)送delete請(qǐng)求,從map和和cache中刪除數(shù)據(jù)。然后再發(fā)送post請(qǐng)求,寫(xiě)入數(shù)據(jù)到map中。最后再發(fā)送get請(qǐng)求,會(huì)發(fā)現(xiàn)現(xiàn)在可以正確的取到值了,控制臺(tái)也沒(méi)有打印從map中獲取數(shù)據(jù)的日志。

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

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

到這里,一個(gè)簡(jiǎn)單的包含增刪改查的緩存應(yīng)用就完成了。

三、劃重點(diǎn)

幾個(gè)注解

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

注意

@Cacheable和@Cacheput都會(huì)將方法的執(zhí)行結(jié)果按指定的key放到緩存中,@Cacheable在執(zhí)行時(shí),會(huì)先檢測(cè)緩存中是否有數(shù)據(jù)存在,如果有,直接從緩存中讀取。如果沒(méi)有,執(zhí)行方法,將返回值放入緩存,而@Cacheput會(huì)先執(zhí)行方法,然后再將執(zhí)行結(jié)果寫(xiě)入緩存。 使用@Cacheput的方法一定會(huì)執(zhí)行

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

總結(jié)

以上所述是小編給大家介紹的Spring Boot 中使用cache緩存的方法,希望對(duì)大家有所幫助,如果大家有任何疑問(wèn)請(qǐng)給我留言,小編會(huì)及時(shí)回復(fù)大家的。在此也非常感謝大家對(duì)腳本之家網(wǎng)站的支持!

相關(guān)文章

  • Jackson自定義序列化反序列化注解加解密字段詳解

    Jackson自定義序列化反序列化注解加解密字段詳解

    這篇文章主要介紹了Jackson自定義序列化反序列化注解加解密字段詳解,一些場(chǎng)景中,數(shù)據(jù)庫(kù)字段用于存儲(chǔ)json格式數(shù)據(jù),處于安全的考慮,該json數(shù)據(jù)中,某些敏感信息字段需要做加密存儲(chǔ),例如身份證號(hào)、手機(jī)號(hào)等,需要的朋友可以參考下
    2023-11-11
  • Java函數(shù)接口和Lambda表達(dá)式深入分析

    Java函數(shù)接口和Lambda表達(dá)式深入分析

    這篇文章主要介紹了Java函數(shù)接口和Lambda表達(dá)式,函數(shù)接口是一個(gè)具有單個(gè)抽象方法的接口,接口設(shè)計(jì)主要是為了支持Lambda表達(dá)式和方法引用,使得Java能更方便地實(shí)現(xiàn)函數(shù)式編程風(fēng)格,需要的朋友可以參考下
    2025-04-04
  • SpringBoot JWT令牌的使用

    SpringBoot JWT令牌的使用

    JWT令牌中包含了一個(gè)用戶(hù)名和哈希值,這些都需要進(jìn)行驗(yàn)證,本文主要介紹了SpringBoot JWT令牌的使用,具有一定的參考價(jià)值,感興趣的可以了解一下
    2024-03-03
  • Spring Boot整合RabbitMQ實(shí)例(Topic模式)

    Spring Boot整合RabbitMQ實(shí)例(Topic模式)

    Topic Exchange 轉(zhuǎn)發(fā)消息主要是根據(jù)通配符。接下來(lái)通過(guò)本文給大家分享Spring Boot整合RabbitMQ實(shí)例(Topic模式),需要的朋友參考下吧
    2017-04-04
  • SpringBoot中的Controller用法示例詳解

    SpringBoot中的Controller用法示例詳解

    Controller是SpringBoot里最基本的組件,他的作用是把用戶(hù)提交來(lái)的請(qǐng)求通過(guò)對(duì)URL的匹配,分配給不同的接收器,再進(jìn)行處理,然后向用戶(hù)返回結(jié)果,這篇文章主要介紹了SpringBoot中的Controller用法,需要的朋友可以參考下
    2023-06-06
  • Java Spring的依賴(lài)注入理解及@Autowired用法示例詳解

    Java Spring的依賴(lài)注入理解及@Autowired用法示例詳解

    文章介紹了Spring依賴(lài)注入(DI)的概念、三種實(shí)現(xiàn)方式(構(gòu)造器、Setter、字段注入),區(qū)分了@Autowired(注入Bean)與@Value(注入簡(jiǎn)單類(lèi)型)的用途,并說(shuō)明@Bean方法參數(shù)可自動(dòng)裝配依賴(lài),無(wú)需顯式注解,感興趣的朋友跟隨小編一起看看吧
    2025-07-07
  • Java自學(xué)書(shū)籍推薦 程序員到架構(gòu)師必看的書(shū)

    Java自學(xué)書(shū)籍推薦 程序員到架構(gòu)師必看的書(shū)

    這篇文章主要為大家推薦了Java程序員到架構(gòu)師自學(xué)書(shū)籍,幫助大家不斷提高自己的專(zhuān)業(yè)水平,感興趣的小伙伴們可以參考一下
    2016-09-09
  • JAVA中Spring Security示例及常見(jiàn)問(wèn)題

    JAVA中Spring Security示例及常見(jiàn)問(wèn)題

    文章概述Spring Security OAuth2與JWT模塊的版本兼容性及遷移建議,強(qiáng)調(diào)2.5.x支持JDK8但已棄用,推薦新項(xiàng)目使用SpringAuthorizationServer(Spring Boot3.x+),并指出依賴(lài)沖突、配置示例及密鑰安全注意事項(xiàng),感興趣的朋友一起看看吧
    2025-07-07
  • Java 8新特性方法引用詳細(xì)介紹

    Java 8新特性方法引用詳細(xì)介紹

    這篇文章主要介紹了Java 8新特性方法引用詳細(xì)介紹的相關(guān)資料,這里對(duì)新特性 方法引用做的資料整理,具有參考價(jià)值,需要的朋友可以參考下
    2016-12-12
  • SpringMVC框架REST架構(gòu)體系原理分析

    SpringMVC框架REST架構(gòu)體系原理分析

    REST:Representational State Transfer,資源表現(xiàn)層狀態(tài)轉(zhuǎn)換,是目前&#12112;較主流的&#12032;種互聯(lián)網(wǎng)軟件架構(gòu),它結(jié)構(gòu)清晰、標(biāo)準(zhǔn)規(guī)范、易于理解、便于擴(kuò)展
    2021-09-09

最新評(píng)論