2013-04-03 40 views
5

我正在編寫一個webapp,並試圖緩存一些從控制器調用的pojos。Spring 3.1.1 MVC @Cacheable未被命中

當我嘗試使用org.springframework.cache.annotation.Cacheable時,我無法獲得任何工作,所以我切換到com.googlecode.ehcaceh.annotations.Cacheable,但仍然無法獲取它緩存。

我的代碼如下所示:

@Controller 
public class Conttroller { 
    @RequestMapping(method = RequestMethod.GET).... 
    public Person getPerson(String id) { 
     LOG.debug("Trying to get resource...); 
     Person person = personService.detect(id); 
     LOG.debug("got person"); 

和服務看起來像:

public class PersonService { 

@Cacheable(cacheName="deviceCache") 
public Person detect(String id) { 
LOG.debug("cache missed") 

我的applicationContext看起來像

<context:component-scan base-package="com.mycompany" /> 


     <ehcache:annotation-driven cache-manager="ehCacheManager" /> 
     <bean id="cacheManager"  class="org.springframework.cache.ehcache.EhCacheCacheManager"> 
      <property name="cacheManager"> 
       <ref bean="ehCacheManager" /> 
      </property> 
     </bean> 
     <bean id="ehCacheManager" class="org.springframework.cache.ehcache.EhCacheManagerFactoryBean" p:configLocation="/META-INF/ehcache.xml" /> 

和我的Ehcache樣子:

<defaultCache eternal="false" maxElementsInMemory="1000" 
    overflowToDisk="false" diskPersistent="false" timeToIdleSeconds="0" 
    timeToLiveSeconds="600" memoryStoreEvictionPolicy="LRU"/> 

<cache name="deviceCache" 
    maxElementsInMemory="100" overflowToDisk="false" diskPersistent="false" 
    timeToIdleSeconds="0" timeToLiveSeconds="300" 
    memoryStoreEvictionPolicy="LRU" /> 

有趣的是,它在緩存我的單元測試細...

@RunWith(SpringJUnit4ClassRunner.class) 
@ContextConfiguration({"classpath:META-INF/applicationContext-test.xml"}) 
public class PersonServiceTest { 

private static final Logger LOG = LoggerFactory.getLogger(PersonServiceTest.class); 
@Test 
public void testCache() { 
    LOG.debug("Getting person..."); 
    Device detect = personService.detect("test"); 
    LOG.debug("Getting person again ..."); 
    detect = personService.detect("test"); 
    LOG.debug("Done"); 
} 

主要生產:

13:45:02.885 [main] DEBUG PersonServiceTest - Getting person... 
13:45:02.887 [main] DEBUG c.g.e.a.i.CacheAttributeSourceImpl - Adding CACHE advised method 'detect' with attribute: CacheableAttributeImpl [cacheInstanceResolver=com.googleco[email protected]5c2bfdff, cacheKeyGenerator=HashCodeCacheKeyGenerator [includeMethod=true, includeParameterTypes=true, useReflection=false, checkforCycles=false], parameterMask=ParameterMask [mask=[]]] 
13:45:02.889 [main] DEBUG c.g.e.a.i.EhCacheInterceptor - Generated key '-1043428721379252' for invocation: ReflectiveMethodInvocation: public abstract com.mycompany.Person com.mycompany.PersonServiceImpl.detect(java.lang.String); target is of class [com..mycompany.PersonServiceImpl] 
13:45:02.889 [main] DEBUG PersonServiceTest - Missed 
13:45:02.927 [main] DEBUG PersonServiceTest - Getting person again ... 
13:45:02.927 [main] DEBUG c.g.e.a.i.EhCacheInterceptor - Generated key '-1043428721379252' for invocation: ReflectiveMethodInvocation: 
13:45:02.927 [main] DEBUG PersonServiceTest - Done 

但我的戰輸出(運行tomcat7/eclipse wtp)是:

DEBUG net.sf.ehcache.config.ConfigurationFactory Configuring ehcache from InputStream 
DEBUG net.sf.ehcache.config.BeanHandler Ignoring ehcache attribute xmlns:xsi 
DEBUG net.sf.ehcache.config.BeanHandler Ignoring ehcache attribute xsi:noNamespaceSchemaLocation 
DEBUG net.sf.ehcache.util.PropertyUtil propertiesString is null. 
DEBUG net.sf.ehcache.config.ConfigurationHelper No CacheManagerEventListenerFactory class specified. Skipping... 
DEBUG net.sf.ehcache.Cache No BootstrapCacheLoaderFactory class specified. Skipping... 
DEBUG net.sf.ehcache.Cache CacheWriter factory not configured. Skipping... 
DEBUG net.sf.ehcache.config.ConfigurationHelper No CacheExceptionHandlerFactory class specified. Skipping... 
DEBUG net.sf.ehcache.Cache No BootstrapCacheLoaderFactory class specified. Skipping... 
DEBUG net.sf.ehcache.Cache CacheWriter factory not configured. Skipping... 
DEBUG net.sf.ehcache.config.ConfigurationHelper No CacheExceptionHandlerFactory class specified. Skipping... 
DEBUG net.sf.ehcache.store.MemoryStore Initialized net.sf.ehcache.store.NotifyingMemoryStore for deviceCache 
DEBUG net.sf.ehcache.statistics.extended.ExtendedStatisticsImpl Mocking Pass-Through Statistic: LOCAL_OFFHEAP_SIZE 
DEBUG net.sf.ehcache.statistics.extended.ExtendedStatisticsImpl Mocking Pass-Through Statistic: LOCAL_OFFHEAP_SIZE_BYTES 
DEBUG net.sf.ehcache.statistics.extended.ExtendedStatisticsImpl Mocking Pass-Through Statistic: LOCAL_DISK_SIZE 
DEBUG net.sf.ehcache.statistics.extended.ExtendedStatisticsImpl Mocking Pass-Through Statistic: LOCAL_DISK_SIZE_BYTES 
DEBUG net.sf.ehcache.statistics.extended.ExtendedStatisticsImpl Mocking Pass-Through Statistic: WRITER_QUEUE_LENGTH 
DEBUG net.sf.ehcache.statistics.extended.ExtendedStatisticsImpl Mocking Pass-Through Statistic: REMOTE_SIZE 
DEBUG net.sf.ehcache.statistics.extended.ExtendedStatisticsImpl Mocking Operation Statistic: OFFHEAP_GET 
DEBUG net.sf.ehcache.statistics.extended.ExtendedStatisticsImpl Mocking Operation Statistic: OFFHEAP_PUT 
DEBUG net.sf.ehcache.statistics.extended.ExtendedStatisticsImpl Mocking Operation Statistic: OFFHEAP_REMOVE 
DEBUG net.sf.ehcache.statistics.extended.ExtendedStatisticsImpl Mocking Operation Statistic: DISK_GET 
DEBUG net.sf.ehcache.statistics.extended.ExtendedStatisticsImpl Mocking Operation Statistic: DISK_PUT 
DEBUG net.sf.ehcache.statistics.extended.ExtendedStatisticsImpl Mocking Operation Statistic: DISK_REMOVE 
DEBUG net.sf.ehcache.statistics.extended.ExtendedStatisticsImpl Mocking Operation Statistic: XA_COMMIT 
DEBUG net.sf.ehcache.statistics.extended.ExtendedStatisticsImpl Mocking Operation Statistic: XA_ROLLBACK 
DEBUG net.sf.ehcache.statistics.extended.ExtendedStatisticsImpl Mocking Operation Statistic: XA_RECOVERY 
DEBUG net.sf.ehcache.Cache Initialised cache: deviceCache 
DEBUG net.sf.ehcache.config.ConfigurationHelper CacheDecoratorFactory not configured. Skipping for 'personCache'. 
DEBUG net.sf.ehcache.config.ConfigurationHelper CacheDecoratorFactory not configured for defaultCache. Skipping for 'personCache'. 
DEBUG com.googlecode.ehcache.annotations.impl.CacheAttributeSourceImpl Adding CACHE advised method 'detect' with attribute: CacheableAttributeImpl [cacheInstanceResolver=com.googleco[email protected]7a1b0c08, cacheKeyGenerator=HashCodeCacheKeyGenerator [includeMethod=true, includeParameterTypes=true, useReflection=false, checkforCycles=false], parameterMask=ParameterMask [mask=[]]] 
Apr 3, 2013 2:03:12 PM org.springframework.web.context.ContextLoader initWebApplicationContext 
DEBUG com.mycompany.Controller trying to get resource' 
DEBUG com.mycompany.PersonServiceImpl Missed 
DEBUG com.mycompany.Controller got person' 
DEBUG com.mycompany.Controller trying to get resource' 
DEBUG com.mycompany.PersonServiceImpl Missed 
DEBUG com.mycompany.Controller got person' 

所以我的問題是,爲什麼它在我的單元測試,而不是webapp?我將如何使用Spring註釋來代替googlecode註釋?

回答

3

即使我有一個接口,我在實現類上有@Cacheable註解。一旦我將它移到接口類中,它就被緩存了。

10

您的PersonService服務未實現接口。的Ehcache - 彈簧 - 註解需要一個接口,如在FAQ描述:

要求1:你的類必須 實現一些(任何)接口。如果你的班級沒有實現一個 接口,這個項目將不能創建一個代理來模擬你的班級,並在你的註釋方法中應用緩存語義。

+0

我用它實現一個接口 – 2013-04-04 21:41:29

+0

是已經有一段時間,因爲我用它,但我依稀記得有一個虛擬方法參數添加到我的緩存無參數的方法之一,甚至有相同的問題,使Ehcache可以用該方法匹配緩存的返回值。值得一試.... – nickdos 2013-04-07 09:41:12

0

您需要在Spring上下文xml或Spring配置文件中啓用eh緩存註釋。例如

<ehcache:annotation-driven cache-manager="ehCacheManager" /> 
相關問題