这篇文章给大家介绍@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进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。