詳談@Cacheable不起作用的原因:bean未序列化問(wèn)題
@Cacheable不起作用的原因:bean未序列化
SpringMVC中將serviceImpl的方法返回值緩存在redis中,發(fā)現(xiàn)@Cacheable失效
是返回的Blogger自定義實(shí)體類沒(méi)有實(shí)現(xiàn)序列化接口
無(wú)法存入到redis中。implements一下Serializable接口即可!
@Cacheable注解式緩存不起作用的情形
@Cacheable注解式緩存使用的要點(diǎn):正確的注解式緩存配置,注解對(duì)象為spring管理的hean,調(diào)用者為另一個(gè)對(duì)象。有些情形下注解式緩存是不起作用的:同一個(gè)bean內(nèi)部方法調(diào)用,子類調(diào)用父類中有緩存注解的方法等。后者不起作用是因?yàn)榫彺媲忻姹仨氉叽聿庞行В@時(shí)可以手動(dòng)使用CacheManager來(lái)獲得緩存效果。
使用注解式緩存的正確方式
<cache:annotation-driven cache-manager="springCacheManager" proxy-target-class="false"/> <bean id="ehcacheManager" class="org.springframework.cache.ehcache.EhCacheManagerFactoryBean"> ? ? <property name="configLocation" value="classpath:ehcache.xml"/> ? ? <property name="cacheManagerName" value="ehcache"/> </bean> <bean id="springCacheManager" class="org.springframework.cache.ehcache.EhCacheCacheManager"> ?? ?<property name="cacheManager" ref="ehcacheManager"/> </bean>
要點(diǎn):@Cacheable(value="必須使用ehcache.xml已經(jīng)定義好的緩存名稱,否則會(huì)拋異常")
@Component public class CacheBean { ?? ?@Cacheable(value="passwordRetryCache",key="#key") ?? ?public String map(String key) { ?? ??? ?System.out.println("get value for key: "+key); ?? ??? ?return "value: "+key; ?? ?} ?? ?public String map2(String key) { ?? ??? ?return map(key); ?? ?} } @RunWith(SpringJUnit4ClassRunner.class) @ContextConfiguration(locations = { "classpath:cache.xml" }) public class CacheTester { ?? ?@Autowired CacheManager cacheManager; ?? ?@Autowired CacheBean cacheBean; ?? ?@Test public void cacheManager() { ?? ??? ?System.out.println(cacheManager); ?? ?} ?? ?@Test public void cacheAnnotation() { ?? ??? ?cacheBean.map("a"); ?? ??? ?cacheBean.map("a"); ?? ??? ?cacheBean.map("a"); ?? ??? ?cacheBean.map("a"); ?? ??? ?System.out.println(cacheManager.getCacheNames()); ?? ?} }
輸出:
get value for key: a
[authorizationCache, authenticationCache, shiro-activeSessionCache, passwordRetryCache]
稍微改造一下,讓ehcache支持根據(jù)默認(rèn)配置自動(dòng)添加緩存空間,這里提供自定義的MyEhCacheCacheManager即可
<bean id="springCacheManager" class="com.itecheast.ite.domain.util.MyEhCacheCacheManager"> ?? ?<property name="cacheManager" ref="ehcacheManager"/> </bean>
另一種改造方式,找不到已定義的緩存空間時(shí)不緩存,或者關(guān)閉全部緩存。把cacheManagers配置去掉就可以關(guān)閉圈閉緩存。
<bean id="springCacheManager" class="org.springframework.cache.support.CompositeCacheManager"> ?? ?<property name="cacheManagers"> ?? ??? ?<list> ?? ??? ??? ?<bean class="org.springframework.cache.ehcache.EhCacheCacheManager"></bean> ?? ??? ??? ?<!-- <bean class="com.itecheast.ite.domain.util.MyEhCacheCacheManager"></bean> 這個(gè)會(huì)自動(dòng)創(chuàng)建緩存空間 --> ?? ??? ?</list> ?? ?</property> ? ? <property name="fallbackToNoOpCache" value="true"/> </bean>
調(diào)用相同類或父類方法沒(méi)有緩存效果:這時(shí)可以選擇手動(dòng)使用CacheManager。
@RunWith(SpringJUnit4ClassRunner.class) @ContextConfiguration(locations = { "classpath:cache.xml" }) public class CacheTester { ?? ?@Test public void cacheAnnotation() { ?? ??? ?this.map("a"); ?? ??? ?this.map("a"); ?? ?} ?? ?@Cacheable(value="passwordRetryCache",key="#key") ?? ?public String map(String key) { ?? ??? ?System.out.println("get value for key: "+key); ?? ??? ?return "value: "+key; ?? ?} }
或者再換一種方式:手動(dòng)使用代理方式調(diào)用同類方法也是可以的
public class CacheBean { ?? ?@Autowired ApplicationContext applicationContext; ?? ?@Cacheable(value="passwordRetryCache",key="#key") ?? ?public String map(String key) { ?//方法不能為private,否則也沒(méi)有緩存效果 ?? ??? ?System.out.println("get value for key: "+key); ?? ??? ?return "value: "+key; ?? ?} ?? ?public String map2(String key) { ?? ??? ?CacheBean proxy = applicationContext.getBean(CacheBean.class); ?? ??? ?return proxy.map(key); //這里使用proxy調(diào)用map就可以緩存,而直接調(diào)用map則沒(méi)有緩存 ?? ?} }
以上為個(gè)人經(jīng)驗(yàn),希望能給大家一個(gè)參考,也希望大家多多支持腳本之家。
相關(guān)文章
Java實(shí)現(xiàn)批量操作Excel的示例詳解
在操作Excel的場(chǎng)景中,通常會(huì)有一些針對(duì)Excel的批量操作,以GcExcel為例,為大家詳細(xì)介紹一下Java是如何實(shí)現(xiàn)批量操作Excel的,需要的可以參考一下2023-07-07Java開(kāi)啟JMX遠(yuǎn)程監(jiān)控服務(wù)配置
這篇文章主要為大家介紹了Java開(kāi)啟JMX遠(yuǎn)程監(jiān)控的服務(wù)配置,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2023-05-05解析MapStruct轉(zhuǎn)換javaBean時(shí)出現(xiàn)的詭異事件
在項(xiàng)目中用到了MapStruct,對(duì)其可以轉(zhuǎn)換JavaBean特別好奇,今天小編給大家分享一個(gè)demo給大家講解MapStruct轉(zhuǎn)換javaBean時(shí)出現(xiàn)的詭異事件,感興趣的朋友一起看看吧2021-09-09SpringMVC通過(guò)Ajax處理Json數(shù)據(jù)的步驟詳解
這篇文章主要介紹了SpringMVC通過(guò)Ajax處理Json數(shù)據(jù)的步驟詳解,本文通過(guò)實(shí)例代碼給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2021-04-04Java中常用緩存Cache機(jī)制的實(shí)現(xiàn)
這篇文章主要介紹了Java中常用緩存Cache機(jī)制的實(shí)現(xiàn)代碼,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2016-10-10