溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務(wù)條款》

@Cacheable不起作用的原因以及bean未序列化問題怎么解決

發(fā)布時間:2022-01-04 00:34:13 來源:億速云 閱讀:726 作者:柒染 欄目:開發(fā)技術(shù)

這篇文章給大家介紹@Cacheable不起作用的原因以及bean未序列化問題怎么解決,內(nèi)容非常詳細(xì),感興趣的小伙伴們可以參考借鑒,希望對大家能有所幫助。

@Cacheable不起作用的原因:bean未序列化

SpringMVC中將serviceImpl的方法返回值緩存在redis中,發(fā)現(xiàn)@Cacheable失效

@Cacheable不起作用的原因以及bean未序列化問題怎么解決

是返回的Blogger自定義實體類沒有實現(xiàn)序列化接口

無法存入到redis中。implements一下Serializable接口即可!

@Cacheable不起作用的原因以及bean未序列化問題怎么解決

@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則沒有緩存
    }
}

關(guān)于@Cacheable不起作用的原因以及bean未序列化問題怎么解決就分享到這里了,希望以上內(nèi)容可以對大家有一定的幫助,可以學(xué)到更多知識。如果覺得文章不錯,可以把它分享出去讓更多的人看到。

向AI問一下細(xì)節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點不代表本網(wǎng)站立場,如果涉及侵權(quán)請聯(lián)系站長郵箱:is@yisu.com進行舉報,并提供相關(guān)證據(jù),一經(jīng)查實,將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI