1

我的带有 Spring 和 ehcache 的 @Cacheable 不起作用,缓存中没有数据。当应用程序调用可缓存方法getFolProfile 时,总是调用数据库而不是缓存。请你告诉我我的代码有什么问题。

我的根上下文.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>

感谢您的帮助米歇尔

4

4 回答 4

2

看起来您正在服务层中定义缓存。在http://docs.spring.io/spring/docs/current/spring-framework-reference/html/cache.html中,特别注明如下:

笔记

<cache:annotation-driven/>仅在定义它的同一应用程序上下文中的 bean 上查找 @Cacheable/@CacheEvict。这意味着,如果您<cache:annotation-driven/>为 DispatcherServlet 放入 WebApplicationContext,它只会检查控制器中的 @Cacheable/@CacheEvict beans,而不您的服务。有关更多信息,请参阅第 16.2 节,“DispatcherServlet”。

于 2013-12-20T06:52:22.673 回答
0

添加这个

<cache:annotation-driven cache-manager="cacheManager"  />

你必须告诉 Spring 缓存管理器在哪里。

于 2013-02-26T09:47:02.760 回答
0

当 proxy-target-class 属性设置为 true 时,将创建基于类的代理。CGLIB 将用于为给定的目标对象创建代理。确保您的依赖项中有 CGLIB。

如果您可以选择,请通过将 proxy-target-class 属性设置为 false 并在您的类上实现至少一个接口来首选 JDK 动态代理。

于 2013-02-26T13:01:26.013 回答
0

请检查您的 ehCache 日志中是否存在以下异常:

java.io.NotSerializableException: com.googlecode.ehcache.annotations.RefreshableCacheEntry

您使用磁盘持久缓存 (diskPersistent=true),因此您必须检查您的 FolProfileForm 对象是否可序列化。从 ehCache 文档:

只有可序列化的数据才能放入 DiskStore。写入和写入磁盘使用 ObjectInputStream 和 Java 序列化机制。任何溢出到磁盘存储的不可序列化数据都将被删除,并引发 NotSerializableException。

可能是您的数据没有放置到您的缓存(文件系统)中,因此它会一次又一次地尝试从方法调用中获取它。您可以使用内存存储缓存,甚至可以保存不可序列化的数据。

于 2015-10-09T16:30:51.747 回答