2016-07-05 11 views
0

Ich versuche, Short Wert mit @Cacheable zu cachen.Wie verwende ich Short Datentyp mit @Cacheable?

@EnableAutoConfiguration 
@EnableCaching 
public class Config { 
    @Bean 
    public CacheManager cacheManager() { 
     return new ConcurrentMapCacheManager(); 
    } 
} 

@Service 
public class MyCacheService { 
    @Cacheable("testcache") 
    public Short getId(String name) { 
     return 1; 
    } 
} 

Ergebnis:

java.lang.NullPointerException 
    at org.springframework.cache.interceptor.AbstractCacheResolver.resolveCaches(AbstractCacheResolver.java:78) ~[spring-context-4.2.6.RELEASE.jar:4.2.6.RELEASE] 
    at org.springframework.cache.interceptor.CacheAspectSupport.getCaches(CacheAspectSupport.java:216) ~[spring-context-4.2.6.RELEASE.jar:4.2.6.RELEASE] 
    at org.springframework.cache.interceptor.CacheAspectSupport$CacheOperationContext.<init>(CacheAspectSupport.java:565) ~[spring-context-4.2.6.RELEASE.jar:4.2.6.RELEASE] 
    at org.springframework.cache.interceptor.CacheAspectSupport.getOperationContext(CacheAspectSupport.java:229) ~[spring-context-4.2.6.RELEASE.jar:4.2.6.RELEASE] 
    at org.springframework.cache.interceptor.CacheAspectSupport$CacheOperationContexts.<init>(CacheAspectSupport.java:508) ~[spring-context-4.2.6.RELEASE.jar:4.2.6.RELEASE] 
    at org.springframework.cache.interceptor.CacheAspectSupport.execute(CacheAspectSupport.java:302) ~[spring-context-4.2.6.RELEASE.jar:4.2.6.RELEASE] 
    at org.springframework.cache.interceptor.CacheInterceptor.invoke(CacheInterceptor.java:61) ~[spring-context-4.2.6.RELEASE.jar:4.2.6.RELEASE] 
    at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179) ~[spring-aop-4.2.6.RELEASE.jar:4.2.6.RELEASE] 
    at org.springframework.aop.framework.CglibAopProxy$DynamicAdvisedInterceptor.intercept(CglibAopProxy.java:655) ~[spring-aop-4.2.6.RELEASE.jar:4.2.6.RELEASE] 

Dieses geworfen wird, weil cacheManager ist null in AbstractCacheResolver. Aber warum?

+0

Haben Sie die Annotation @Configuration? – Jango

+0

ja oder natürlich habe ich es. – membersound

Antwort

1

Nun, auf den ersten Blick sieht Ihre Konfiguration (meistens) korrekt aus. Allerdings sagt es uns auch nicht die ganze Geschichte, d. H. In welchem ​​Laufzeitkontext Ihre Anwendung läuft.

Sie scheinen Spring Boot (?) Bei Ihrer Verwendung von @EnableAutoConfiguration zu verwenden. Sie sagen, Sie haben die @Configuration Annotation noch keinen Beweis dafür erbracht. Vielleicht erklärt @AutoConfiguration entgegen der landläufigen Meinung nicht @Configuration für Sie; @SpringBootApplication Annotation tut (speziell, here).

Wie auch immer, ich habe eine einfache Spring Boot Anwendung zusammengestellt, die Ihren Beispielcode demonstriert. Es funktioniert wie erwartet.

package org.examples.spring.boot.caching; 

import static org.assertj.core.api.Assertions.assertThat; 

import org.springframework.beans.factory.annotation.Autowired; 
import org.springframework.boot.CommandLineRunner; 
import org.springframework.boot.SpringApplication; 
import org.springframework.boot.autoconfigure.SpringBootApplication; 
import org.springframework.cache.annotation.Cacheable; 
import org.springframework.cache.annotation.EnableCaching; 
import org.springframework.cache.concurrent.ConcurrentMapCacheManager; 
import org.springframework.context.annotation.Bean; 
import org.springframework.stereotype.Service; 

@SpringBootApplication 
@EnableCaching 
public class ConcurrentMapCachingExample implements CommandLineRunner { 

    public static void main(String[] args) { 
    SpringApplication.run(ConcurrentMapCachingExample.class, args); 
    } 

    @Autowired 
    private ExampleCacheableService exampleService; 

    @Override 
    public void run(String... args) throws Exception { 
    assertThat(exampleService.isCacheMiss()).isFalse(); 
    assertThat(exampleService.computeValue("one").intValue()).isEqualTo(1); 
    assertThat(exampleService.isCacheMiss()).isTrue(); 
    assertThat(exampleService.computeValue("one").intValue()).isEqualTo(1); 
    assertThat(exampleService.isCacheMiss()).isFalse(); 
    } 
} 

@Service 
class ExampleCacheableService { 

    boolean cacheMiss; 

    boolean isCacheMiss() { 
    boolean cacheMiss = this.cacheMiss; 
    this.cacheMiss = false; 
    return cacheMiss; 
    } 

    @Cacheable("Example") 
    public Short computeValue(String cacheKey) { 
    System.out.printf("Computing value for [%s]%n", cacheKey); 
    cacheMiss = true; 
    return 1; 
    } 
} 

Beachten Sie auch, die für Sie @SpringBootApplication Anmerkung declares die @EnableAutoConfiguration Anmerkung gegeben, und der Frühlings Autokonfiguration Unterstützung des Starts erkennt automatisch Caching-Provider auf dem Classpath, dann nur durch die @Cacheable Anmerkung auf Ihrer @Service Anwendungskomponente mit zusammen mit der @EnableCaching Annotation in Ihrer Konfiguration, dies ist genug für Spring Boot zu (automatisch) konfigurieren Sie eine CacheManager für Sie.

Daher ist die folgende @Bean Definition ist nicht notwendig ...

@Bean 
ConcurrentMapCacheManager cacheManager() { 
    return new ConcurrentMapCacheManager(); 
} 

die Spring Boot's Reference Guide für mehr Details.

+0

Vielen Dank für den detaillierten Einblick. Ich weiß noch nicht, warum es in meinem Fall nicht geklappt hat. Aber Ihre Erklärung beweist, dass es im Allgemeinen keine Probleme mit dem Code geben sollte. – membersound