詳談@Cacheable不起作用的原因:bean未序列化問題
@Cacheable不起作用的原因:bean未序列化
SpringMVC中將serviceImpl的方法返回值緩存在redis中,發(fā)現(xiàn)@Cacheable失效

是返回的Blogger自定義實體類沒有實現(xiàn)序列化接口
無法存入到redis中。implements一下Serializable接口即可!

@Cacheable注解式緩存不起作用的情形
@Cacheable注解式緩存使用的要點:正確的注解式緩存配置,注解對象為spring管理的hean,調(diào)用者為另一個對象。有些情形下注解式緩存是不起作用的:同一個bean內(nèi)部方法調(diào)用,子類調(diào)用父類中有緩存注解的方法等。后者不起作用是因為緩存切面必須走代理才有效,這時可以手動使用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已經(jīng)定義好的緩存名稱,否則會拋異常")
@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)配置自動添加緩存空間,這里提供自定義的MyEhCacheCacheManager即可
<bean id="springCacheManager" class="com.itecheast.ite.domain.util.MyEhCacheCacheManager"> ?? ?<property name="cacheManager" ref="ehcacheManager"/> </bean>
另一種改造方式,找不到已定義的緩存空間時不緩存,或者關(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> 這個會自動創(chuàng)建緩存空間 --> ?? ??? ?</list> ?? ?</property> ? ? <property name="fallbackToNoOpCache" value="true"/> </bean>
調(diào)用相同類或父類方法沒有緩存效果:這時可以選擇手動使用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;
?? ?}
}或者再換一種方式:手動使用代理方式調(diào)用同類方法也是可以的
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調(diào)用map就可以緩存,而直接調(diào)用map則沒有緩存
?? ?}
}以上為個人經(jīng)驗,希望能給大家一個參考,也希望大家多多支持腳本之家。
相關(guān)文章
解決spring?data?jpa?saveAll()?保存過慢問題
這篇文章主要介紹了解決spring?data?jpa?saveAll()保存過慢問題,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教2021-11-11
處理Log4j2不能打印行號的問題(AsyncLogger)
這篇文章主要介紹了處理Log4j2不能打印行號的問題(AsyncLogger),具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教2021-12-12
詳解SpringBoot 發(fā)布ApplicationEventPublisher和監(jiān)聽ApplicationEvent事
這篇文章主要介紹了詳解SpringBoot 發(fā)布ApplicationEventPublisher和監(jiān)聽ApplicationEvent事件,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧2019-06-06
Spring使用Redis限制用戶登錄失敗的次數(shù)及暫時鎖定用戶登錄權(quán)限功能
這篇文章主要介紹了Spring使用Redis限制用戶登錄失敗的次數(shù)及暫時鎖定用戶登錄權(quán)限功能,本文通過實例代碼給大家介紹的非常詳細(xì),需要的朋友可以參考下2024-02-02
IDEA下lombok安裝及找不到get,set的問題的解決方法
這篇文章主要介紹了IDEA下lombok安裝及找不到get,set的問題的解決方法,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2020-04-04
Java用?Gradle配置compile及implementation和api的區(qū)別
這篇文章主要介紹了Java用Gradle配置compile及implementation和api的區(qū)別,文章圍繞主題的相關(guān)資料展開詳細(xì)的內(nèi)容介紹,具有一定的參考價值,需要的小伙伴可以參考一下2022-06-06

