【spring指南系列】使用Spring緩存數(shù)據(jù)

翻譯自:https://spring.io/guides/gs/caching/
譯者:知秋
來(lái)源:極樂(lè)科技

本指南將指導(dǎo)您完成在Spring所托管bean上啟用緩存的過(guò)程。

What you’ll build

您將構(gòu)建一個(gè)應(yīng)用程序交惯,在一個(gè)簡(jiǎn)單的book repository中啟用緩存。

What you’ll need

  • 約15分鐘
  • 最喜歡的文本編輯器或IDE
  • JDK 1.8或更高版本
  • Gradle 2.3+Maven 3.0+
  • 您也可以從本指南導(dǎo)入代碼望迎,以及直接在Spring Tool Suite(STS)中查看網(wǎng)頁(yè),并從那 里開(kāi)始工作 凌外。

How to complete this guide

與大多數(shù)【Spring 入門指南】一樣Spring Guides辩尊,您可以從頭開(kāi)始并完成每個(gè)步驟,也可以繞過(guò)已經(jīng)熟悉的基本設(shè)置步驟康辑。 無(wú)論如何摄欲,你最終得到工作代碼。

當(dāng)你做完這一切, 你可以根據(jù) gs-caching/complete中的代碼檢查結(jié)果胸墙。

Build with Gradle

首先你設(shè)置一個(gè)基本的構(gòu)建腳本。 你可以使用任何你喜歡的一個(gè)來(lái)構(gòu)建項(xiàng)目按咒,當(dāng)使用Spring構(gòu)建應(yīng)用程序時(shí)迟隅,但是需要使用Gradle和Maven 來(lái)寫(xiě)你的代碼。 如果你不熟悉任何一個(gè)励七,請(qǐng)參考使用Gradle構(gòu)建Java項(xiàng)目使用Maven構(gòu)建Java項(xiàng)目智袭。

Create the directory structure

在您選擇的項(xiàng)目目錄中,創(chuàng)建以下子目錄結(jié)構(gòu); 例如掠抬,在* nix*系統(tǒng)上使用

└── src
    └── main
        └── java
            └── hello

Create a Gradle build file

下面是 initial Gradle build file吼野。

build.gradle

buildscript {
repositories {
mavenCentral()
}
dependencies {
classpath("org.springframework.boot:spring-boot-gradle-plugin:1.4.3.RELEASE")
}
}

apply plugin: 'java'
apply plugin: 'eclipse'
apply plugin: 'idea'
apply plugin: 'org.springframework.boot'

jar {
baseName = 'gs-caching'
version = '0.1.0'
}

repositories {
mavenCentral()
}

sourceCompatibility = 1.8
targetCompatibility = 1.8

dependencies {
compile("org.springframework.boot:spring-boot-starter-cache")
}

Spring Boot gradle插件提供了許多方便的功能:

  • 它收集類路徑上的所有jar,并構(gòu)建一個(gè)單獨(dú)的两波,可運(yùn)行的“über-jar”箫锤,這使得執(zhí)行和傳遞服務(wù)更加方便。
  • 它搜索public static void main()方法來(lái)標(biāo)記為可運(yùn)行類雨女。
  • 它提供了一個(gè)內(nèi)置的依賴解析器谚攒,設(shè)置版本號(hào)匹配Spring Boot dependencies, 你可以覆蓋任何你想要的版本氛堕,但它會(huì)默認(rèn)為Boot的選擇的版本集馏臭。

Build with Maven

首先你設(shè)置一個(gè)基本的構(gòu)建腳本。 你可以使用任何你喜歡的一個(gè)來(lái)構(gòu)建項(xiàng)目讼稚,當(dāng)使用Spring構(gòu)建應(yīng)用程序括儒,但是需要使用Maven來(lái)構(gòu)建你的代碼。 如果你不熟悉Maven锐想,請(qǐng)參考使用Maven構(gòu)建Java項(xiàng)目.

Create the directory structure

在您選擇的項(xiàng)目目錄中帮寻,創(chuàng)建以下子目錄結(jié)構(gòu); 例如,在* nix*系統(tǒng)上使用

└── src
    └── main
        └── java
            └── hello

pom.xml

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>

<groupId>org.springframework</groupId>
<artifactId>gs-caching</artifactId>
<version>0.1.0</version>

<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>1.4.3.RELEASE</version>
</parent>

<properties>
<java.version>1.8</java.version>
</properties>

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

<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>

</project>

Spring Boot Maven插件 提供了許多方便的功能:

  • 它收集類路徑上的所有jar赠摇,并構(gòu)建一個(gè)單獨(dú)的固逗,可運(yùn)行的“über-jar”浅蚪,這使得執(zhí)行和運(yùn)輸服務(wù)更加方便。
  • 它搜索public static void main()方法來(lái)標(biāo)記為可運(yùn)行類烫罩。
  • 它提供了一個(gè)內(nèi)置的依賴解析器惜傲,設(shè)置版本號(hào)匹配Spring Boot dependencies. 你可以覆蓋任何你想要的版本,但它會(huì)默認(rèn)為Boot的選擇的版本集贝攒。

Build with your IDE

閱讀如何通過(guò)本指南直接導(dǎo)入Spring Tool Suite盗誊。
閱讀如何在IntelliJ IDEA上使用本指南。

Create a book repository

首先隘弊,讓我們?yōu)槟愕腷ook創(chuàng)建一個(gè)非常簡(jiǎn)單的模型

src/main/java/hello/Book.java

package hello;
public class Book {
private String isbn;
private String title;

public Book(String isbn, String title) {
this.isbn = isbn;
this.title = title;
}

public String getIsbn() {
return isbn;
}

public void setIsbn(String isbn) {
this.isbn = isbn;
}

public String getTitle() {
return title;
}

public void setTitle(String title) {
this.title = title;
}

@Override
public String toString() {
return "Book{" + "isbn='" + isbn + '\'' + ", title='" + title + '\'' + '}';
}
}

和該model的存儲(chǔ)庫(kù):
src/main/java/hello/BookRepository.java

package hello;

public interface BookRepository {

Book getByIsbn(String isbn);

}

您可以使用Spring Data在很多的SQL或NoSQL stores中提供repository倉(cāng)庫(kù)的實(shí)現(xiàn)哈踱,但是出于本指南的目的, 將使用模擬一些延遲(網(wǎng)絡(luò)服務(wù)梨熙,慢延遲等)進(jìn)行簡(jiǎn)單地的實(shí)現(xiàn)嚣鄙。

src/main/java/hello/SimpleBookRepository.java

package hello;
import org.springframework.stereotype.Component;

@Component
public class SimpleBookRepository implements BookRepository {

@Override
public Book getByIsbn(String isbn) {
simulateSlowService();
return new Book(isbn, "Some book");
}

// Don't do this at home
private void simulateSlowService() {
try {
long time = 3000L;
Thread.sleep(time);
} catch (InterruptedException e) {
throw new IllegalStateException(e);
}
}

}

simulateSlowService是故意在每個(gè)getByIsbn調(diào)用中插入一個(gè)三秒延遲。 這是一個(gè)例子串结,稍后哑子,你可以通過(guò)加入緩存來(lái)看到加速的效果。

Using the repository

接下來(lái)肌割,連接repository庫(kù)并使用它訪問(wèn)一些書(shū)卧蜓。

src/main/java/hello/Application.java

package hello;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

@SpringBootApplication
public class Application {

public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}

}
  • @ SpringBootApplication是一個(gè)方便的注解,添加了以下所有內(nèi)容:
  • @ Configuration將類標(biāo)記為應(yīng)用程序上下文的bean定義的來(lái)源把敞。
  • @ EnableAutoConfiguration告訴Spring Boot根據(jù)類路徑設(shè)置弥奸,其他bean和各種屬性設(shè)置開(kāi)始添加bean。
  • 通常你會(huì)為Spring MVC應(yīng)用程序添加@ EnableWebMvc奋早,但是Spring Boot在類路徑上看到** spring-webmvc **時(shí)會(huì)自動(dòng)添加它盛霎。這將應(yīng)用程序標(biāo)記為Web應(yīng)用程序,并激活關(guān)鍵行為耽装,如設(shè)置一個(gè)“DispatcherServlet”愤炸。
  • @ ComponentScan告訴Spring在hello包中尋找其他組件,配置和服務(wù)掉奄,允許它找到控制器规个。

main()方法使用Spring Boot的SpringApplication.run()方法來(lái)啟動(dòng)應(yīng)用程序。你有注意到一行XML姓建?沒(méi)有** web.xml **文件诞仓。這個(gè)Web應(yīng)用程序是100%純Java,你不必處理配置任何管道或基礎(chǔ)設(shè)施速兔。
還有一個(gè)CommandLineRunner墅拭,注入BookRepository和 用不同的參數(shù)調(diào)用它幾次。

src/main/java/hello/AppRunner.java

package hello;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.boot.CommandLineRunner;
import org.springframework.stereotype.Component;

@Component
public class AppRunner implements CommandLineRunner {

private static final Logger logger = LoggerFactory.getLogger(AppRunner.class);

private final BookRepository bookRepository;

public AppRunner(BookRepository bookRepository) {
this.bookRepository = bookRepository;
}

@Override
public void run(String... args) throws Exception {
logger.info(".... Fetching books");
logger.info("isbn-1234 -->" + bookRepository.getByIsbn("isbn-1234"));
logger.info("isbn-4567 -->" + bookRepository.getByIsbn("isbn-4567"));
logger.info("isbn-1234 -->" + bookRepository.getByIsbn("isbn-1234"));
logger.info("isbn-4567 -->" + bookRepository.getByIsbn("isbn-4567"));
logger.info("isbn-1234 -->" + bookRepository.getByIsbn("isbn-1234"));
logger.info("isbn-1234 -->" + bookRepository.getByIsbn("isbn-1234"));
}

}

如果你嘗試在此時(shí)運(yùn)行應(yīng)用程序涣狗,您會(huì)注意到它很慢谍婉,即使您幾次檢索完全相同的書(shū)舒憾。

2014-06-05 12:15:35.783 ... : .... Fetching books
2014-06-05 12:15:40.783 ... : isbn-1234 -->Book{isbn='isbn-1234', title='Some book'}
2014-06-05 12:15:43.784 ... : isbn-1234 -->Book{isbn='isbn-1234', title='Some book'}
2014-06-05 12:15:46.786 ... : isbn-1234 -->Book{isbn='isbn-1234', title='Some book'}

從時(shí)間戳可以看出,每本書(shū)花了大約三秒鐘來(lái)檢索屡萤,即使它是相同的標(biāo)題被重復(fù)抓取珍剑。

Enable caching

讓我們?cè)谀愕腟impleBookRepository上啟用緩存掸宛,這樣書(shū)就會(huì)被緩存在books緩存中死陆。

src/main/java/hello/SimpleBookRepository.java

package hello;

import org.springframework.cache.annotation.Cacheable;
import org.springframework.stereotype.Component;

@Component
public class SimpleBookRepository implements BookRepository {

@Override
@Cacheable("books")
public Book getByIsbn(String isbn) {
simulateSlowService();
return new Book(isbn, "Some book");
}

// Don't do this at home
private void simulateSlowService() {
try {
long time = 3000L;
Thread.sleep(time);
} catch (InterruptedException e) {
throw new IllegalStateException(e);
}
}

}

您現(xiàn)在需要啟用緩存注解的處理

src/main/java/hello/Application.java

package hello;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cache.annotation.EnableCaching;

@SpringBootApplication
@EnableCaching
public class Application {

public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}

}

@EnableCaching注解觸發(fā)檢查并處理每個(gè)Spring bean用于存在對(duì)公共方法的緩存注解。如果找到這樣的注解唧瘾,則自動(dòng)創(chuàng)建代理以攔截方法調(diào)用并相應(yīng)地處理緩存行為措译。

緩存處理的相應(yīng)注解是CacheableCachePutCacheEvict.有關(guān)更多詳細(xì)信息饰序,可以參考javadocs和文檔领虹。

Spring Boot會(huì)自動(dòng)配置一個(gè)合適的CacheManager,作為相關(guān)緩存求豫。有關(guān)更多詳細(xì)信息塌衰,請(qǐng)參閱Spring Boot文檔

我們的示例不使用特定的緩存庫(kù)蝠嘉,因此我們的緩存存儲(chǔ)是使用ConcurrentHashMap的簡(jiǎn)單回退最疆。緩存抽象支持各種各樣的緩存庫(kù),并完全符合JSR-107(JCache)蚤告。

Build an executable JAR

您可以使用Gradle或Maven從命令行運(yùn)行應(yīng)用程序努酸。 或者,您可以構(gòu)建單個(gè)可執(zhí)行文件杜恰,其中包含所有必需的依賴關(guān)系获诈,類和資源,并運(yùn)行它心褐。 這使得在整個(gè)開(kāi)發(fā)生命周期中舔涎,易于跨不同環(huán)境將服務(wù)作為應(yīng)用程序進(jìn)行發(fā)布,維護(hù)版本和部署等等逗爹。

如果您使用Gradle终抽,可以使用./gradlew bootRun運(yùn)行應(yīng)用程序。 或者你可以使用./gradlew build來(lái)構(gòu)建JAR文件桶至。 然后可以運(yùn)行JAR文件:
java -jar build/libs/gs-caching-0.1.0.jar

如果您使用Maven昼伴,可以使用./mvnw spring-boot:run運(yùn)行應(yīng)用程序。 或者你可以用./mvnw clean package構(gòu)建JAR文件镣屹。 然后可以運(yùn)行JAR文件:
java -jar target/gs-caching-0.1.0.jar

**上面的過(guò)程將創(chuàng)建一個(gè)可運(yùn)行的JAR圃郊。 您也可以選擇build a classic WAR file

Test the application

現(xiàn)在緩存已啟用,您可以再次執(zhí)行它女蜈,并通過(guò)添加或不使用相同的isbn的額外調(diào)用查看差異持舆。 你應(yīng)該可以看到其產(chǎn)生明顯的區(qū)別色瘩。

2016-09-01 11:12:47.033 .. : .... Fetching books
2016-09-01 11:12:50.039 .. : isbn-1234 -->Book{isbn='isbn-1234', title='Some book'}
2016-09-01 11:12:53.044 .. : isbn-4567 -->Book{isbn='isbn-4567', title='Some book'}
2016-09-01 11:12:53.045 .. : isbn-1234 -->Book{isbn='isbn-1234', title='Some book'}
2016-09-01 11:12:53.045 .. : isbn-4567 -->Book{isbn='isbn-4567', title='Some book'}
2016-09-01 11:12:53.045 .. : isbn-1234 -->Book{isbn='isbn-1234', title='Some book'}
2016-09-01 11:12:53.045 .. : isbn-1234 -->Book{isbn='isbn-1234', title='Some book'}

This excerpt from the console shows that the first time to fetch each title took three seconds, but each subsequent call was near instantaneous.
從控制臺(tái)的這段日志顯示,第一次獲取每個(gè)標(biāo)題花了三秒鐘逸寓,但每個(gè)后續(xù)的訪問(wèn)接近瞬間居兆。

最后###

恭喜! 你剛剛通過(guò)Springcache在托管bean上啟用了緩存竹伸。

系列回顧:

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末泥栖,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子勋篓,更是在濱河造成了極大的恐慌吧享,老刑警劉巖,帶你破解...
    沈念sama閱讀 222,183評(píng)論 6 516
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件譬嚣,死亡現(xiàn)場(chǎng)離奇詭異钢颂,居然都是意外死亡,警方通過(guò)查閱死者的電腦和手機(jī)拜银,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,850評(píng)論 3 399
  • 文/潘曉璐 我一進(jìn)店門殊鞭,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái),“玉大人尼桶,你說(shuō)我怎么就攤上這事操灿。” “怎么了疯汁?”我有些...
    開(kāi)封第一講書(shū)人閱讀 168,766評(píng)論 0 361
  • 文/不壞的土叔 我叫張陵牲尺,是天一觀的道長(zhǎng)。 經(jīng)常有香客問(wèn)我幌蚊,道長(zhǎng)谤碳,這世上最難降的妖魔是什么? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 59,854評(píng)論 1 299
  • 正文 為了忘掉前任溢豆,我火速辦了婚禮蜒简,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘漩仙。我一直安慰自己搓茬,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 68,871評(píng)論 6 398
  • 文/花漫 我一把揭開(kāi)白布队他。 她就那樣靜靜地躺著卷仑,像睡著了一般。 火紅的嫁衣襯著肌膚如雪麸折。 梳的紋絲不亂的頭發(fā)上锡凝,一...
    開(kāi)封第一講書(shū)人閱讀 52,457評(píng)論 1 311
  • 那天,我揣著相機(jī)與錄音垢啼,去河邊找鬼窜锯。 笑死张肾,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的锚扎。 我是一名探鬼主播吞瞪,決...
    沈念sama閱讀 40,999評(píng)論 3 422
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼驾孔!你這毒婦竟也來(lái)了芍秆?” 一聲冷哼從身側(cè)響起,我...
    開(kāi)封第一講書(shū)人閱讀 39,914評(píng)論 0 277
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤助币,失蹤者是張志新(化名)和其女友劉穎浪听,沒(méi)想到半個(gè)月后螟碎,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體眉菱,經(jīng)...
    沈念sama閱讀 46,465評(píng)論 1 319
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 38,543評(píng)論 3 342
  • 正文 我和宋清朗相戀三年掉分,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了俭缓。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 40,675評(píng)論 1 353
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡酥郭,死狀恐怖华坦,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情不从,我是刑警寧澤惜姐,帶...
    沈念sama閱讀 36,354評(píng)論 5 351
  • 正文 年R本政府宣布,位于F島的核電站椿息,受9級(jí)特大地震影響歹袁,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜寝优,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 42,029評(píng)論 3 335
  • 文/蒙蒙 一条舔、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧乏矾,春花似錦孟抗、人聲如沸。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 32,514評(píng)論 0 25
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)。三九已至捷沸,卻和暖如春摊沉,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背亿胸。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 33,616評(píng)論 1 274
  • 我被黑心中介騙來(lái)泰國(guó)打工坯钦, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留预皇,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 49,091評(píng)論 3 378
  • 正文 我出身青樓婉刀,卻偏偏與公主長(zhǎng)得像吟温,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子突颊,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,685評(píng)論 2 360

推薦閱讀更多精彩內(nèi)容