2013-04-03 8 views
5

Ich schreibe eine Webapp, und und versuche, einige pojos zu cachen, die vom Controller aufgerufen werden.Frühling 3.1.1 MVC @Cacheable nicht getroffen werden

Ich konnte nichts bekommen, wenn ich org.springframework.cache.annotation.Cacheable versuchte, also wechselte ich zu com.googlecode.ehcaceh.annotations.Cacheable, und ich bekomme es immer noch nicht Zwischenspeicher.

Mein Code sieht wie folgt aus:

@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"); 

und der Service wie folgt aussieht:

public class PersonService { 

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

Mein application wie

sieht
<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" /> 

und meine ehcache wie folgt aussieht:

<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" /> 

Was interessant ist, ist, dass es in meinem Unit-Test ...

@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"); 
} 

, die die feinen Caches:

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 

Aber der Ausgang meines Krieges (läuft durch tomcat7/eclipse wtp) ist:

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' 

Also meine Frage ist, warum funktioniert es in meinem Komponententest, und nicht Webapp? Und wie würde ich anstelle der Googlecode-Annotation die Spring-Annotation verwenden?

Antwort

3

Obwohl ich eine Schnittstelle hatte, hatte ich die Annotation @Cacheable auf der Implementierungsklasse. Sobald ich es in die Interface-Klasse verschoben habe, wurde es zwischengespeichert.

10

Ihr PersonService Dienst implementiert keine Schnittstelle. Ehcache-Feder-Annotationen erfordern eine Schnittstelle, wie sie in den FAQ beschrieben:

Anforderung 1: Ihre Klasse muss implementieren einig (jede) Schnittstelle. Wenn Ihre Klasse keine Schnittstelle implementiert, kann dieses Projekt keinen Proxy erstellen, um Ihre Klasse nachzuahmen und die Cache-Semantik um Ihre annotierten Methoden anzuwenden.

+0

Ich habe das gleiche Problem, auch mit ihm eine Schnittstelle –

+0

Implementierung eine Weile wird seit ich es benutzt, aber ich erinnere mich vage, keine-args Methoden ein Dummy-Methode Argument zu einem meiner gecached hinzuzufügen, so dass Ehcache konnte den zwischengespeicherten Rückgabewert mit dieser Methode abgleichen. Einen Versuch wert ... – nickdos

0

Sie müssen die eh-Cache-Annotation in Ihrer Spring-Kontext-XML- oder Spring-Konfigurationsdatei aktivieren. zum Beispiel

<ehcache:annotation-driven cache-manager="ehCacheManager" /> 
Verwandte Themen