springboot 整合EhCache實(shí)現(xiàn)單服務(wù)緩存的操作方法
在Spring框架內(nèi)我們首選Spring Cache作為緩存框架的門(mén)面,之所以說(shuō)它是門(mén)面,是因?yàn)樗惶峁┙涌趯拥亩x以及AOP注解等,不提供緩存的具體存取操作。緩存的具體存儲(chǔ)還需要具體的緩存存儲(chǔ),比如EhCache 、Redis等。Spring Cache與緩存框架的關(guān)系有點(diǎn)像SLF4j與logback、log4j的關(guān)系。
- EhCache 適用于單體應(yīng)用的緩存,當(dāng)應(yīng)用進(jìn)行分布式部署的時(shí)候,各應(yīng)用的副本之間緩存是不同步的。EhCache 由于沒(méi)有獨(dú)立的部署服務(wù),所以它的緩存和應(yīng)用的內(nèi)存是耦合在一起的,當(dāng)緩存數(shù)據(jù)量比較大的時(shí)候要注意系統(tǒng)資源能不能滿足應(yīng)用內(nèi)存的要求。
- redis由于是可以獨(dú)立部署的內(nèi)存數(shù)據(jù)庫(kù)服務(wù),所以它能夠滿足應(yīng)用分布式部署的緩存集中存儲(chǔ)的要求,也就是分布式部署的應(yīng)用使用一份緩存,從而緩存自然是同步的。但是對(duì)于一些小規(guī)模的應(yīng)用,額外引入了redis服務(wù),增加了運(yùn)維的成本。
所以,比如我們自己開(kāi)發(fā)一個(gè)小博客,自己的服務(wù)器又沒(méi)有很多的資源獨(dú)立部署redis服務(wù),用EHCache作為緩存是比較好的選擇。如果是企業(yè)級(jí)用戶量,使用redis獨(dú)立部署的服務(wù)作為緩存是更好的選擇。
一、整合Spring Cache 與Ehcache
通過(guò)上一小節(jié)的學(xué)習(xí),可以使用Spring cache通過(guò)注解的方式來(lái)操作緩存,一定程度上減少了程序員緩存操作代碼編寫(xiě)量。注解添加和移除都很方便,不與業(yè)務(wù)代碼耦合,容易維護(hù)。 這一部分內(nèi)容是沒(méi)有變化的,所以我們?nèi)匀皇褂肧pring Cache。
第一步:pom.xml 添加 Spring cache 和 Ehcache的 jar 依賴:
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-cache</artifactId> </dependency> <dependency> <groupId>net.sf.ehcache</groupId> <artifactId>ehcache</artifactId> </dependency>
第二步:添加入口啟動(dòng)類 @EnableCaching 注解開(kāi)啟 Caching,實(shí)例如下。
@EnableCaching
在Spring Boot中通過(guò)@EnableCaching
注解自動(dòng)化配置合適的緩存管理器(CacheManager),Spring Boot根據(jù)下面的順序去偵測(cè)緩存提供者,也就是說(shuō)Spring Cache支持下面的這些緩存框架:
- Generic
- JCache (JSR-107) (EhCache 3, Hazelcast, Infinispan, and others)
- EhCache 2.x(發(fā)現(xiàn)ehcache的bean,就使用ehcache作為緩存)
- Hazelcast
- Infinispan
- Couchbase
- Redis
- Caffeine
- Simple
yml配置
需要說(shuō)明的是
config:classpath:/ehcache.xml
可以不用寫(xiě),因?yàn)槟J(rèn)就是這個(gè)路徑。但ehcache.xml
必須有。
spring: cache: type: ehcache ehcache: config: classpath:/ehcache.xml
在 resources 目錄下,添加 ehcache 的配置文件 ehcache.xml ,文件內(nèi)容如下:
<ehcache> <diskStore path="java.io.tmpdir/cache_dongbb"/> <defaultCache maxElementsInMemory="10000" eternal="false" timeToIdleSeconds="120" timeToLiveSeconds="120" overflowToDisk="false" diskPersistent="false" diskExpiryThreadIntervalSeconds="120" /> <cache name="user_detail" maxElementsInMemory="10000" eternal="true" overflowToDisk="true" diskPersistent="true" diskExpiryThreadIntervalSeconds="600"/> </ehcache> conds="600"/> </ehcache>
配置含義:
- name:緩存名稱,與緩存注解的value(cacheNames)屬性值相同。
- maxElementsInMemory:緩存最大個(gè)數(shù)。
- eternal:緩存對(duì)象是否永久有效,一但設(shè)置了,timeout將不起作用。
- timeToIdleSeconds:設(shè)置對(duì)象在失效前的允許閑置時(shí)間(單位:秒)。僅當(dāng)eternal=false對(duì)象不是永久有效時(shí)使用,可選屬性,默認(rèn)值是0,也就是可閑置時(shí)間無(wú)窮大。
- timeToLiveSeconds:設(shè)置對(duì)象在失效前允許存活時(shí)間(單位:秒)。最大時(shí)間介于創(chuàng)建時(shí)間和失效時(shí)間之間。僅當(dāng)eternal=false對(duì)象不是永久有效時(shí)使用,默認(rèn)是0.,也就是對(duì)象存活時(shí)間無(wú)窮大。
- overflowToDisk:當(dāng)內(nèi)存中對(duì)象數(shù)量達(dá)到maxElementsInMemory時(shí),Ehcache將會(huì)對(duì)象寫(xiě)到磁盤(pán)中。
- diskSpoolBufferSizeMB:這個(gè)參數(shù)設(shè)置DiskStore(磁盤(pán)緩存)的緩存區(qū)大小。默認(rèn)是30MB。每個(gè)Cache都應(yīng)該有自己的一個(gè)緩沖區(qū)。
- maxElementsOnDisk:硬盤(pán)最大緩存?zhèn)€數(shù)。
- diskPersistent:是否緩存虛擬機(jī)重啟期數(shù)據(jù)。
- diskExpiryThreadIntervalSeconds:磁盤(pán)失效線程運(yùn)行時(shí)間間隔,默認(rèn)是120秒。
- memoryStoreEvictionPolicy:當(dāng)達(dá)到maxElementsInMemory限制時(shí),Ehcache將會(huì)根據(jù)指定的策略去清理內(nèi)存。默認(rèn)策略是LRU(最近最少使用)。你可以設(shè)置為FIFO(先進(jìn)先出)或是LFU(較少使用)。
- clearOnFlush:內(nèi)存數(shù)量最大時(shí)是否清除。
- diskStore 則表示臨時(shí)緩存的硬盤(pán)目錄。
“java.io.tmpdir”操作系統(tǒng)緩存的臨時(shí)目錄,不同操作系統(tǒng)的緩存臨時(shí)目錄不一樣,在Windows的緩存目錄為
C:\\Users\\登錄用戶~(yú)1\\AppData\\Local\\Temp\\
; Linux目錄為/tmp
二、緩存的使用方法
緩存的使用方法仍然是Spring Cache的注解,使用方法是一樣的,參考本專欄文章《結(jié)合redis詳述聲明式緩存注解的使用-Cacheable、CacheEvict、CachePut、Caching》。
三、緩存使用中的坑
注意:@Cacheable 注解在對(duì)象內(nèi)部調(diào)用不會(huì)生效。這個(gè)坑不是單獨(dú)針對(duì)EhCache的,只要使用Spring Cache都會(huì)有這個(gè)問(wèn)題。
@Component public class ClassA { @Override public void MethodA(String username) { MethodA1(username); //緩存失效,@Cacheable 注解在對(duì)象內(nèi)部調(diào)用不會(huì)生效 } @Cacheable(value = USER_DETAIL,key = "#username") public void MethodA1(String username) { //執(zhí)行方法體 } }
原因: Spring 緩存注解是基于Spring AOP切面,必須走代理才能生效,同類調(diào)用或者子類調(diào)用父類帶有緩存注解的方法時(shí)屬于內(nèi)部調(diào)用,沒(méi)有走代理,所以注解不生效。
解決辦法: 將緩存方法,放在一個(gè)單獨(dú)的類中
@Component public class ClassA { @Resource ClassB classB; @Override public void methodA(String username) { classB.methodA1(username); //緩存失效,@Cacheable 注解在對(duì)象內(nèi)部調(diào)用不會(huì)生效 } }
@Component public class ClassB { @Cacheable(value = USER_DETAIL,key = "#username") public void methodA1(String username) { //執(zhí)行方法體 } }
到此這篇關(guān)于springboot 整合EhCache實(shí)現(xiàn)單服務(wù)緩存的文章就介紹到這了,更多相關(guān)springboot 單服務(wù)緩存內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
SparkSQL使用IDEA快速入門(mén)DataFrame與DataSet的完美教程
本文給大家介紹使用idea開(kāi)發(fā)Spark SQL 的詳細(xì)過(guò)程,本文通過(guò)實(shí)例代碼給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友參考下吧2021-08-08Spring MVC通過(guò)添加自定義注解格式化數(shù)據(jù)的方法
這篇文章主要給大家介紹了關(guān)于Spring MVC通過(guò)添加自定義注解格式化數(shù)據(jù)的方法,文中先對(duì)springmvc 自定義注解 以及自定義注解的解析進(jìn)行了詳細(xì)的介紹,相信會(huì)對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧。2017-11-11使用Java實(shí)現(xiàn)百萬(wàn)Excel數(shù)據(jù)導(dǎo)出
這篇文章主要為大家詳細(xì)介紹了如何使用Java實(shí)現(xiàn)百萬(wàn)Excel數(shù)據(jù)導(dǎo)出,文中的示例代碼講解詳細(xì),具有一定的借鑒價(jià)值,有需要的小伙伴可以參考一下2024-03-03Java8中關(guān)于Function.identity()的使用
這篇文章主要介紹了Java8中關(guān)于Function.identity()的使用,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2023-05-05Spring Boot整合Web項(xiàng)目常用功能詳解
這篇文章主要介紹了Spring Boot整合Web項(xiàng)目常用功能詳解,在Web應(yīng)用開(kāi)發(fā)過(guò)程中,可以通過(guò)Spring Boot的Starter來(lái)將這些常用功能進(jìn)行整合與集中維護(hù),以達(dá)到開(kāi)箱即用的目的。,需要的朋友可以參考下2019-06-06