版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進行舉報或認領(lǐng)
文檔簡介
第7章SpringBoot與緩存第7章SpringBoot與緩存7.1JCache(JSR-107)規(guī)范7.2
緩存抽象與緩存注解7.3EhCache2.x緩存7.4Redis緩存27.1JCache(JSR-107)規(guī)范緩存在數(shù)據(jù)訪問量比較大的系統(tǒng)中用的還是非常多的,為了統(tǒng)一緩存的開發(fā)規(guī)范,提升系統(tǒng)的擴展性,J2EE發(fā)布了JSR-107規(guī)范。1.什么是JSR-107規(guī)范JSR是JavaSpecificationRequests的縮寫,意思是Java規(guī)范提案,2012年10月26日JSR規(guī)范委員會發(fā)布了JSR107(JCacheAPI)。JCache規(guī)范定義了一種對Java對象臨時在內(nèi)存中進行緩存的方法,包括對象的創(chuàng)建、共享訪問、假脫機(spooling)、失效、各JVM的一致性等,可被用戶緩存最經(jīng)常訪問的數(shù)據(jù)。37.1JCache(JSR-107)規(guī)范
JavaCaching定義了5個核心接口,具體如下:(1)CachingProvider:定義了創(chuàng)建、配置、獲取、管理和控制多個CacheManager。一個應(yīng)用可以在運行期間訪問多個CachingProvider。(2)CacheManager:定義了創(chuàng)建、配置、獲取、管理和控制多個唯一命名的Cache,這些Cache存在于CacheManager的上下文中。一個CacheManager僅被一個CachingProvider所擁有。(3)Cache:是一個類似Map的數(shù)據(jù)結(jié)構(gòu)并臨時存儲以key為索引的值。一個Cache僅被一個CacheManager所擁有。(4)Entry:是一個存儲在Cache中的key-value對。(5)Expiry:每一個存儲在Cache中的條目有一個定義的有效期。一旦超過這個時間,條目為過期的狀態(tài)。一旦過期,條目將不可訪問、更新和刪除。緩存有效期可以通過ExpiryPolicy設(shè)置。47.1JCache(JSR-107)規(guī)范
2.應(yīng)用調(diào)用緩存應(yīng)用首先會先調(diào)用CachingProvider(緩存提供者),緩存提供者管理了多個CacheManager(緩存管理器),緩存管理器中才是真正的Cache緩存。緩存管理器中可以管理不同類型的緩存,比如Redis、EhCache等。在具體緩存組件中,我們還可以設(shè)置不同模塊的緩存,比如Redis中我們可以來緩存商品信息、熱點數(shù)據(jù)等不同模塊數(shù)據(jù),每個緩存都是Entry<K,V>鍵值對類型,并且可以對緩存設(shè)置Expiry過期時間,指定緩存存活時間,如圖7-1所示。JSR-107作為一個Java規(guī)范,它定義的都是一些接口,類似于JDBC規(guī)范。直接面向接口編程,需要用到哪種緩存的實現(xiàn),我們來直接引入該緩存實現(xiàn)即可,系統(tǒng)就能運行起來,使用JSR-107時需引入如下依賴。5<dependency><groupId>javax.cache</groupId><artifactId>cache-api</artifactId></dependency>7.2緩存抽象與緩存注解
1.Spring緩存抽象Spring框架從3.1開始定義了org.springframework.cache.Cache和org.springframework.cache.CacheManager接口,提供對緩存功能的聲明,能夠與多種流行的緩存實現(xiàn)集成。SpringCache不是具體的緩存技術(shù),而是基于具體的緩存產(chǎn)品(如EhCache、Redis等)的共性進行了一層抽象,可以通過簡單的配置切換底層使用的緩存。Spring定義了自己緩存抽象用于統(tǒng)一緩存操作,僅僅提供抽象,而不是具體實現(xiàn),只要實現(xiàn)Cache和CacheManager接口,就可以接入Spring通過緩存注解的方式使用緩存(一些主流的緩存都提供該抽象的實現(xiàn))。
67.2緩存抽象與緩存注解緩存抽象中定義Cache和CacheManager兩個接口如下:
Cache:緩存接口,組件規(guī)范定義,包含緩存的各種操作集合。Spring提供了各種xxxCache的實現(xiàn),如RedisCache,EhCacheCache,ConcurrentMapCache等。
CacheManager:緩存管理器,管理各種緩存組件(Cache),簡單來說就是用于存放cache,Spring默認也提供了一系列管理器的實現(xiàn)。
抽象的核心是將緩存應(yīng)用于Java方法,從而減少基于緩存中可用信息的執(zhí)行次數(shù)。每次調(diào)用需要緩存功能的方法時,Spring會檢查指定參數(shù)和指定目標方法是否已經(jīng)被調(diào)用過,如果有就直接從緩存中獲取方法調(diào)用后的結(jié)果,如果沒有就調(diào)用方法并將緩存結(jié)果返回給用戶,下次直接從緩存獲取。
77.2緩存抽象與緩存注解2.Spring緩存注解使用SpringCache需要我們做兩方面的事,一是聲明某些方法使用緩存,二是配置Spring對Cache的支持。Spring對Cache的支持有基于注解和基于XML配置兩種方式,下面針對SpringBoot中的緩存注解及相關(guān)屬性講解。(1)@Cacheable(2)@CachePut(3)@CacheEvict(4)@Caching(5)@CacheConfig(6)@EnableCaching87.2緩存抽象與緩存注解(1)@Cacheable:該注解是由Spring框架提供,可作用于類或方法(一般標注在service層,通常用在數(shù)據(jù)查詢方法上),用于對方法的查詢結(jié)果進行緩存存儲。@Cacheable注解的執(zhí)行順序是,先進行緩存查詢,如果為空則進行方法查詢,并將結(jié)果進行緩存;如果緩存中有數(shù)據(jù),不進行方法查詢,而是直接使用緩存數(shù)據(jù)。@Cacheable注解提供了多個屬性,用于對緩存存儲進行相關(guān)配置,具體屬性及說明如表。9屬性名說明value/cacheNames指定緩存空間的名稱,必配屬性,這兩個屬性二選一使用key指定緩存數(shù)據(jù)的key,默認使用方法參數(shù)值,可用SpEL表單式keyGenerator指定緩存數(shù)據(jù)的key的生成器,與key屬性二選一使用cacheManager指定緩存管理器cacheResolver指定緩存解析器,與cacheManager屬性二選一使用condition指定在符合某條件下,進行數(shù)據(jù)緩存unless指定在符合某條件下,不進行數(shù)據(jù)緩存Sync指定是否使用異步緩存,默認值為false7.2緩存抽象與緩存注解(2)@CachePut:該注解是由Spring框架提供的,可以作用于類或方法(一般標注在service層,通常用在數(shù)據(jù)更新方法上),作用是更新緩存數(shù)據(jù)。@CachePut注解的執(zhí)行順序是,先進行方法調(diào)用,然后將方法結(jié)果更新到緩存中。@CachePut注解也提供了多個屬性,這些屬性與@Cacheable注解的屬性完全相同。(3)@CacheEvict:該注解由Spring框架提供的,可以作用于類或方法(一般標注在service層,通常用在數(shù)據(jù)刪除方法上),作用是刪除數(shù)據(jù)緩存。@CacheEvict注解的執(zhí)行順序是,先進行方法調(diào)用,然后清除緩存。@CacheEvict注解提供了多個屬性,與@Cacheable注解的屬性基本相同。除此之外,還提供了兩個特殊屬性:
allEntries、beforeinvocation。107.2緩存抽象與緩存注解(4)@Caching:該注解用于同時添加多個緩存注解,定義復(fù)雜規(guī)則的數(shù)據(jù)緩存。該注解作用于類或者方法。@Caching注解包含cacheable、put和evict三個屬性,作用等于@Cacheable、@CachePut和@CacheEvict。(5)@CacheConfig:該注解作用于類,用于統(tǒng)籌管理類中所有使用@Cacheable、@CachePut和@CacheEvict注解標注的方法中的公共屬性,這些公共屬性包括cacheNames、keyGenerator、cacheManager和cacheResolver。(6)@EnableCaching:該注解是Spring框架提供的,SpringBoot框架對該注解進行了繼承,用于開啟基于注解的緩存支持,該注解需要配置類上(在SpringBoot中,通常配置在項目的啟動類上)。117.2緩存抽象與緩存注解3.SpringBoot支持的緩存組件在SpringBoot中,數(shù)據(jù)的管理存儲依賴于Spring框架中cache相關(guān)的org.springframework.cache.Cache和org.springframework.cache.CacheManager緩存管理接口。如果程序中沒有定義類型為CacheManager的Bean組件或者名為cacheResolver的CacheResolver緩存解析器,SpringBoot將根據(jù)以下指定的順序嘗試并啟用以下緩存組件。Generic、JCache(JSR-107)(EhCache3、Hazelcast、Infinispan等)、EhCache2.x、Hazelcast、Infinispan、Couchbase、Redis、Caffeine、Simple。在項目中添加某個緩存管理組件(例如EhCache2.x)后,SpringBoot項目會選擇并啟用對應(yīng)的緩存管理器。127.2緩存抽象與緩存注解
如果項目中同時添加了多個緩存組件,且沒有指定緩存管理器或者緩存解析器(CacheManager或者CacheResolver),那么SpringBoot會按照上述順序在添加的多個緩存中優(yōu)先啟用指定的緩存組件進行緩存管理。SpringBoot默認緩存管理中,沒有添加任何緩存管理組件能實現(xiàn)緩存管理。這是因為開啟緩存管理后,SpringBoot會按照上述列表順序查找有效的緩存組件進行緩存管理,如果沒有任何緩存組件,會默認使用最后一個Simple緩存組件進行管理。Simple緩存組件是SpringBoot默認的緩存管理組件,它默認使用內(nèi)存中的ConcurrentHashMap進行緩存存儲,所以在沒有添加任何第三方緩存組件的情況下,也可以實現(xiàn)內(nèi)存中的緩存管理。在默認情況下使用的是Simple簡單緩存,不建議在正式環(huán)境中使用這種緩存管理方式。137.2緩存抽象與緩存注解4.SprigBoot默認緩存管理Spring框架支持透明地向應(yīng)用程序添加緩存并對緩存進行管理,其管理緩存的核心是將緩存應(yīng)用于操作數(shù)據(jù)的方法中,從而減少操作數(shù)據(jù)的次數(shù),同時不會對程序本身造成任何干擾。SpringBoot繼承了Spring的緩存管理功能,通過@EnableCaching注解開啟基于注解的緩存支持,自動化配置合適的緩存管理器(CacheManager)。下面針對SpringBoot支持的默認緩存管理,結(jié)合數(shù)據(jù)庫的訪問操作對SpringBoot的緩存管理進行講解,步驟如下。(1)使用MySQL數(shù)據(jù)庫創(chuàng)建一個名為chapter07的數(shù)據(jù)庫,并新建user數(shù)據(jù)表,包含id、username、password屬性,預(yù)先插入幾條測試記錄。147.2緩存抽象與緩存注解(2)新建一個SpringBoot工程chapter07cache,Group和Packagename為com.yzpc,在Dependencies依賴中選擇Web節(jié)點下的SpringWeb依賴,SQL節(jié)點下的SpringDataJPA依賴、MySQLDriver依賴和I/O節(jié)點下的Springcacheabstraction依賴,單擊Finish按鈕,如圖7-2所示。pom.xml中自動添加的依賴代碼,如下所示。(3)在項目的src/main/resources/路徑下的application.properties配置文件中加入數(shù)據(jù)庫連接配置信息(與5.2.1小節(jié)中介紹的一致),接下來設(shè)置JPA的基本配置以及Springcache的目標緩存管理器配置,配置如下所示。(4)在項目的src/main/java/路徑下的com.yzpc包中,新建一個pojo包,并在該包中新建與數(shù)據(jù)表user對應(yīng)的實體類User,添加JPA對應(yīng)的注解進行映射配置,代碼如下所示。15<!--開啟cache緩存--><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-cache</artifactId></dependency><!--省略SpringWeb、SpringDataJPA、MySQLDriver依賴代碼-->spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driverspring.datasource.url=jdbc:mysql://localhost:3306/chapter07?serverTimezone=UTCspring.datasource.username=rootspring.datasource.password=123456spring.jpa.database=mysqlspring.jpa.show-sql=truespring.jpa.hibernate.ddl-auto=update#Springcache目標緩存管理器默認為simple,如果不加,會按順序查找到該緩存組件spring.cache.type=simplepackagecom.yzpc.pojo;importjavax.persistence.*;@Entity(name="user")
//
設(shè)置ORM實體類,并指定映射的表名publicclassUserimplementsSerializable{
@Id//表示映射對應(yīng)的主鍵//設(shè)置主鍵自增策略
@GeneratedValue(strategy=GenerationType.AUTO)
privateintid;
privateStringusername;
privateStringpassword;
//此處省略構(gòu)造方法
//此處省略相應(yīng)屬性的setter/getter方法
//重寫toString方法}}(5)在項目的src/main/java/路徑下的com.yzpc包中,新建一個repository包,并在該包中新建一個用于操作User實體的接口UserRepository,該接口繼承自JpaRepository,也可在該接口中,自己定義相應(yīng)的方法,代碼如下所示。
(6)在項目的src/main/java/路徑下的com.yzpc包中,新建一個service包,并在該包中新建一個用于User相關(guān)業(yè)務(wù)操作的UserService類,代碼如下所示。(7)在項目的src/main/java/路徑下的com.yzpc包中,新建一個controller包,并在該包中新建一個訪問控制類UserController,代碼如下所示。
16publicinterfaceUserRepositoryextendsJpaRepository<User,Integer>{}@ServicepublicclassUserService{
@Autowired
UserRepositoryuserRepository;
//根據(jù)id查詢用戶信息
@Cacheable(cacheNames="user",unless="#result==null")
publicUserfindUserById(intid){
Optional<User>user=userRepository.findById(id);
if(user.isPresent()){
returnuser.get();}
returnnull;}}@RestControllerpublicclassUserController{
@Autowired
UserServiceuserService;
@GetMapping("/findUserById")
publicUserfindUserById(intid){
Useruser=userService.findUserById(id);
returnuser;}}7.2緩存抽象與緩存注解7.2緩存抽象與緩存注解(8)在項目的Chapter07cacheApplication啟動類上使用@EnableCaching注解開啟基于注解的緩存支持,內(nèi)容如下所示。(9)啟動項目,訪問http://localhost:8080/findUserById?id=3,查詢id為3的用戶信息,調(diào)用方法查詢數(shù)據(jù)庫,并將查詢結(jié)果數(shù)據(jù)存儲到緩存user中,頁面查詢結(jié)果如圖7-3所示。此時控制臺輸出Hibernate的查詢語句,如圖7-4所示。再次訪問http://localhost:8080/findUserById?id=3,此時控制臺沒有任何輸出內(nèi)容,但頁面還是輸出前面的查詢結(jié)果,這表明沒有調(diào)用查詢方法,頁面的數(shù)據(jù)直接從數(shù)據(jù)緩存中獲得。17@SpringBootApplication@EnableCaching//開啟SpringBoot基于注解的緩存管理支持publicclassChapter07cacheApplication{
publicstaticvoidmain(String[]args){
SpringApplication.run(Chapter07cacheApplication.class,args);}}7.3EhCache2.x緩存EhCache是一種廣泛使用的開源的高性能Java分布式緩存框架,有很高的拓展性和伸縮性,廣泛使用在各種Java項目中(如Hibernate默認使用Ehcache作為二級緩存)。在SpringBoot中,只要配置一個配置文件就可以將EhCache集成到項目中。EhCache2.x緩存的使用步驟如下。(1)復(fù)制7.2小節(jié)的chapter07cache項目并重命名為chapter07ehcache。用IDEA打開該項目,選擇chapter07ehcache項目,點擊,選擇Refactor
Rename命令,然后輸入新的Module名稱為chapter07ehcache,單擊OK按鈕,如圖7-5所示。打開pom.xml文件,修改<artifactId>和<name>標簽下的名稱為chapter07ehcache。187.3EhCache2.x緩存
右擊啟動類Chapter07cacheApplication,選擇Refactor
Rename命令,修改新名稱為Chapter07ehcacheApplication,如圖7-6所示,在圖7-6中,單擊Refactor按鈕,在彈出的RenameTests對話框中,選中class前面的復(fù)選框,通知修改測試類,單擊OK按鈕,如圖7-7所示。
單擊Run菜單下“EidtConfigurations…”選項,在彈出的對話框中,將Name后名稱修改為Chapter07ehcacheApplication,單擊“OK”按鈕,如圖所示。(2)在pom.xml文件中,添加Ehcache2.x緩存依賴坐標,內(nèi)容如下所示。通過配置屬性spring.cache.type來指定緩存管理器,修改perties配置文件,添加代碼如下。19<!--此處省略其它依賴代碼--><!--ehcache的緩存坐標--><dependency><groupId>net.sf.ehcache</groupId><artifactId>ehcache</artifactId></dependency>#Springcache目標緩存管理器修改為ehcachespring.cache.type=ehcache7.3EhCache2.x緩存
(3)在項目的src/main/resources/目錄下創(chuàng)建ehcache.xml文件,作為Ehcache緩存的配置文件,配置如下所示。這是一個常規(guī)的Ehcache配置文件,提供兩個緩存策略,一個是默認的,另一個名為user。
(4)修改UserRepository接口,添加一個修改方法update(),并在方法上方添加@Query注解,代碼如下所示。
(5)修改UserService類,在該類中添加增刪改查的方法,分別為save()、delete()、update()、findOne()方法,在相應(yīng)的方法上加上緩存注解,代碼如下所示。20<?xmlversion="1.0"encoding="UTF-8"?><ehcache><diskStorepath="java.io.tmpdir/cache"/><defaultCache
maxElementsInMemory="10000"
eternal="false"
timeToIdleSeconds="120"
timeToLiveSeconds="120"
overflowToDisk="false"
diskPersistent="false"
diskExpiryThreadIntervalSeconds="120"/><cachename="user"
maxElementsInMemory="10000"
eternal="true"
timeToIdleSeconds="120"
timeToLiveSeconds="120"
overflowToDisk="true"
diskPersistent="true"
diskExpiryThreadIntervalSeconds="600"/></ehcache>publicinterfaceUserRepositoryextendsJpaRepository<User,Integer>{
@Transactional@Modifying@Query("updateuserusetu.username=?1,u.password=?2whereu.id=?3")
publicvoidupdate(Stringusername,Stringpassword,intid);}1
@Cacheable(cacheNames="user",unless="#reult==null")
publicUserfindOne(intid){
Optional<User>u=userRepository.findById(id);
System.out.println("為Key="+u.get().getId()+"的數(shù)據(jù)做了緩存");
returnu.get();}
@CachePut(value="user",key="#result.id")
publicUsersave(Useruser){
Useru=userRepository.save(user);
System.out.println("為Key="+u.getId()+"的數(shù)據(jù)做了緩存");
returnu;}@CachePut(value="user",key="#result.id")
publicUserupdate(Useruser){
userRepository.update(user.getUsername(),user.getPassword(),user.getId());
System.out.println("為key="+user.getId()+"數(shù)據(jù)記錄做了緩存");
returnuser;}
@CacheEvict(value="user")
publicvoiddelete(intid){
System.out.println("刪除了Key="+id+"的數(shù)據(jù)緩存");}7.3EhCache2.x緩存
(6)修改UserController類,在該類中添加相應(yīng)增刪改查方法并添加訪問映射,代碼如下所示。(7)啟動項目,第一次訪問http://localhost:8080/findOne?id=4,將調(diào)用方法查詢數(shù)據(jù)庫。并將數(shù)據(jù)存儲到緩存,此時控制臺輸出如圖7-6所示,同時網(wǎng)頁顯示數(shù)據(jù)如圖7-7所示。
再次訪問http://localhost:8080/findOne?id=4,此時控制臺沒有任何輸出,這表明沒有調(diào)用查詢方法,頁面顯示的數(shù)據(jù)是直接從緩存中獲取的。
21
@GetMapping("/findOne")
publicUserfindOne(intid){
returnuserService.findOne(id);}
@GetMapping("/save")
publicUsersave(Useruser){
returnuserService.save(user);}
@GetMapping("/update")
publicUserupdate(Useruser){
Useru=userService.update(user);
returnu;}
@GetMapping("/delete")
publicStringdelete(intid){
userService.delete(id);
return"刪除key="+id+"的數(shù)據(jù)緩存";}7.3EhCache2.x緩存訪問http://localhost:8080/save?username=lisi&password=lisi,此時控制臺輸出如圖7-8所示,頁面顯示數(shù)據(jù)如圖7-9所示。插入數(shù)據(jù)后,訪問http://localhost:8080/findOne?id=5,控制臺無任何輸出,從緩存直接獲得id為5的數(shù)據(jù),頁面顯示結(jié)果與圖7-9相同。
訪問http://localhost:8080/update?id=5&username=李四&password=123456,此時控制臺輸出如圖7-10所示,頁面顯示數(shù)據(jù)如圖7-11所示。修改數(shù)據(jù)后,訪問http://localhost:8080/findOne?id=5,控制臺無任何輸出,從緩存直接獲得id為5的數(shù)據(jù),頁面顯示結(jié)果與圖7-11相同。227.3EhCache2.x緩存訪問http://localhost:8080/delete?id=5,刪除key為5的緩存,控制臺和瀏覽器都輸出“刪除key=5的數(shù)據(jù)緩存”。再次訪問http://localhost:8080/findOne?id=5,此時重新做了緩存,控制臺輸出結(jié)果如圖7-12所示。237.4Redis緩
溫馨提示
- 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
- 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
- 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負責(zé)。
- 6. 下載文件中如有侵權(quán)或不適當內(nèi)容,請與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準確性、安全性和完整性, 同時也不承擔用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。
最新文檔
- 牛羊零售商店購銷合同
- 建筑垃圾處理棄土堆放合同
- 茶樓裝修合同
- 標準合同復(fù)工協(xié)議
- 借款合同中的擔保方式選擇與分析
- 物流資源共享合作合同
- 銀行環(huán)境清潔責(zé)任合同
- 租賃服務(wù)合同簽訂應(yīng)注意的法律問題
- 購房合同簽訂流程詳解
- 國際供應(yīng)鏈合同
- 2024年02月天津市口腔醫(yī)院派遣制人員招考聘用40人筆試歷年(2016-2023年)真題薈萃帶答案解析
- 聲明書:個人婚姻狀況聲明
- 幼兒園年檢整改專項方案
- 新管徑流速流量對照表
- 20以內(nèi)退位減法口算練習(xí)題100題30套(共3000題)
- 咯血病人做介入手術(shù)后的護理
- 境外投資環(huán)境分析報告
- 便攜式氣體檢測儀使用方法課件
- 《壓力平衡式旋塞閥》課件
- 信貸支持生豬養(yǎng)殖行業(yè)報告
- 物聯(lián)網(wǎng)與人工智能技術(shù)融合發(fā)展年度報告
評論
0/150
提交評論