我的@Cacheable与Spring和ehcache不起作用,没有数据放在缓存上。 当应用程序调用可缓存方法getFolProfile时,数据库始终是调用而不是缓存。 请问,我可以告诉我代码中的错误。
我的root-context.xml:
<cache:annotation-driven proxy-target-class="true"/>
<bean id="ehcache" class="org.springframework.cache.ehcache.EhCacheManagerFactoryBean" p:configLocation="classpath:/cache/ehcache.xml" />
<bean id="cacheManager" class="org.springframework.cache.ehcache.EhCacheCacheManager" p:cacheManager-ref="ehcache"/>
我的服务:
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.stereotype.Service;
@Service
public class FolManager {
@Autowired
FolDao folDao;
@Cacheable(value = "oneCache", key = "#email")
public FolProfileForm getFolProfile(String email) {
return folDao.retrieveByLogin(email);
}
}
我的ehcache.xml:
<?xml version="1.0" encoding="UTF-8"?>
<ehcache xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="http://ehcache.org/ehcache.xsd">
<diskStore path="c:/tmp" />
<defaultCache maxElementsInMemory="10000" eternal="false" timeToIdleSeconds="120"
timeToLiveSeconds="120" overflowToDisk="true" diskSpoolBufferSizeMB="30" maxElementsOnDisk="10000000"
diskPersistent="false" diskExpiryThreadIntervalSeconds="120" memoryStoreEvictionPolicy="LRU" />
<cache name="oneCache" maxElementsInMemory="100000" maxElementsOnDisk="10000000" eternal="true" diskPersistent="true"
overflowToDisk="true" diskSpoolBufferSizeMB="20" memoryStoreEvictionPolicy="LFU" />
</ehcache>
感谢您的帮助 米歇尔
答案 0 :(得分:2)
您似乎在服务层中定义了缓存。在http://docs.spring.io/spring/docs/current/spring-framework-reference/html/cache.html,具体指出如下:
请注意
<cache:annotation-driven/>
仅查找@ Cacheable / @ CacheEvict bean在其定义的相同应用程序上下文中。这意味着 如果你将<cache:annotation-driven/>
放在WebApplicationContext中 对于DispatcherServlet,它只检查@ Cacheable / @ CacheEvict 控制器中的bean,而不是您的服务。见16.2节, “DispatcherServlet”了解更多信息。
答案 1 :(得分:0)
添加此
<cache:annotation-driven cache-manager="cacheManager" />
你必须告诉Spring缓存管理器的位置。
答案 2 :(得分:0)
当proxy-target-class属性设置为true时,将创建基于类的代理。 CGLIB将用于为给定的目标对象创建代理。请确保您的依赖项中包含CGLIB。
如果您有选择,可以通过将proxy-target-class属性设置为false并在类上至少实现一个接口来选择JDK动态代理。
答案 3 :(得分:0)
请检查您的ehCache日志,了解以下例外情况:
java.io.NotSerializableException: com.googlecode.ehcache.annotations.RefreshableCacheEntry
您使用磁盘持久性缓存(diskPersistent = true),因此您必须检查FolProfileForm对象是否可以序列化。 来自ehCache文档:
只有Serializable的数据可以放在DiskStore中。使用ObjectInputStream和Java序列化机制写入磁盘和从磁盘写入。将删除溢出到磁盘存储区的任何非可序列化数据,并抛出NotSerializableException。
可能是您的数据未放置到缓存(文件系统)的情况,因此它会一次又一次地尝试从方法调用中获取它。 您可以使用内存存储缓存,甚至可以保存不可序列化的数据。