您好,登錄后才能下訂單哦!
這篇文章給大家介紹@Cacheable不起作用的原因以及bean未序列化問題怎么解決,內容非常詳細,感興趣的小伙伴們可以參考借鑒,希望對大家能有所幫助。
SpringMVC中將serviceImpl的方法返回值緩存在redis中,發現@Cacheable失效
無法存入到redis中。implements一下Serializable接口即可!
@Cacheable注解式緩存使用的要點:正確的注解式緩存配置,注解對象為spring管理的hean,調用者為另一個對象。有些情形下注解式緩存是不起作用的:同一個bean內部方法調用,子類調用父類中有緩存注解的方法等。后者不起作用是因為緩存切面必須走代理才有效,這時可以手動使用CacheManager來獲得緩存效果。
<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>
要點:@Cacheable(value="必須使用ehcache.xml已經定義好的緩存名稱,否則會拋異常")
@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支持根據默認配置自動添加緩存空間,這里提供自定義的MyEhCacheCacheManager即可
<bean id="springCacheManager" class="com.itecheast.ite.domain.util.MyEhCacheCacheManager"> <property name="cacheManager" ref="ehcacheManager"/> </bean>
另一種改造方式,找不到已定義的緩存空間時不緩存,或者關閉全部緩存。把cacheManagers配置去掉就可以關閉圈閉緩存。
<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> 這個會自動創建緩存空間 --> </list> </property> <property name="fallbackToNoOpCache" value="true"/> </bean>
調用相同類或父類方法沒有緩存效果:這時可以選擇手動使用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; } }
或者再換一種方式:手動使用代理方式調用同類方法也是可以的
public class CacheBean { @Autowired ApplicationContext applicationContext; @Cacheable(value="passwordRetryCache",key="#key") public String map(String key) { //方法不能為private,否則也沒有緩存效果 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調用map就可以緩存,而直接調用map則沒有緩存 } }
關于@Cacheable不起作用的原因以及bean未序列化問題怎么解決就分享到這里了,希望以上內容可以對大家有一定的幫助,可以學到更多知識。如果覺得文章不錯,可以把它分享出去讓更多的人看到。
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。