2017-02-01 2 views
3

Ich arbeite an einer Spring Boot App, wo ich sowohl verteilte (z. B. Hazelcast) als auch lokale (z. B. Guava) Caches verwenden muss. Gibt es eine Möglichkeit, Spring Cache zu konfigurieren, beide zu verwenden, wenn Sie @Cacheable verwenden und basierend auf dem Cache-Namen entscheiden, welche Implementierung benötigt wird?Mehrere Cache-Implementierungen mit Spring Cache verwenden

Ich habe versucht, eine Konfiguration für beide HZ und Guava zu erstellen, die die Cache-Namen im Inneren definieren, aber Spring beschwert sich, dass es den Cache-Namen nicht finden konnte, der von HZ behandelt werden soll. Wenn ich ausschließlich HZ oder Guava benutze, arbeiten sie.

+0

Mit ['CompositeCacheManager'] (http://docs.spring.io/spring/docs/current/javadoc-api/org/springframework/cache/support/CompositeCacheManager.html) sollte es möglich sein, aber Sie werden möglicherweise muss die Boot-Autokonfiguration deaktiviert werden (ich bin nicht so vertraut mit Boot). –

+0

Überprüfen Sie diese Antwort - http://stackoverflow.com/a/21992641/865403 –

Antwort

4

Welche Implementierung wird basierend auf dem Cache-Namen benötigt?

nicht basierend auf dem Namen Cache aber ja basierend auf CacheManager seiner möglichen erklären eine von ihnen als Primary CacheManager wie folgt:

@Configuration 
@EnableCaching 
@PropertySource(value = { "classpath:/cache.properties" }) 
public class CacheConfig { 

    @Bean 
    @Primary 
    public CacheManager hazelcastCacheManager() { 
     ClientConfig config = new ClientConfig(); 
     HazelcastInstance client = HazelcastClient.newHazelcastClient(config); 
     return new HazelcastCacheManager(client); 
    } 

    @Bean 
    public CacheManager guavaCacheManager() { 
     GuavaCacheManager cacheManager = new GuavaCacheManager("mycache"); 
      CacheBuilder<Object, Object> cacheBuilder = CacheBuilder.newBuilder() 
      .maximumSize(100) 
      .expireAfterWrite(10, TimeUnit.MINUTES); 
      cacheManager.setCacheBuilder(cacheBuilder); 
      return cacheManager; 
    } 

} 

Und es in der Klassenbezeichnung angeben wie:

@Service 
@CacheConfig(cacheManager="hazelcastCacheManager") 
public class EmployeeServiceImpl implements IEmployeeService { 

} 

Oder auf Methodenebene wie:

@Service 
public class EmployeeServiceImpl implements IEmployeeService { 

    @Override 
    @Cacheable(value = "EMPLOYEE_", key = "#id", cacheManager= "guavaCacheManager") 
    public Employee getEmployee(int id) { 
     return new Employee(id, "A"); 
    } 

} 

Wenn Sie nur Cache-Namen bleiben müssen, dann können Sie mehrere CacheManager.

+0

Ich folgte Ihrer Lösung, aber habe diese Ausnahme beim Start: 'java.lang.IllegalStateException: Kein CacheResolver angegeben, und keine eindeutige Bean des Typs CacheManager gefunden. Markieren Sie einen als primary (oder geben Sie ihm den Namen 'cacheManager') oder deklarieren Sie einen bestimmten CacheManager, der als Standard dient. 'Ich habe versucht, den Namen der Fehlermeldung zu verwenden, aber es hat nicht geholfen. Irgendeine Idee dazu? – Balazs

+0

Egal, '@ Primary' hat funktioniert. – Balazs

+1

Danke für die Hilfe, es funktioniert perfekt! Es ist eine Schande, dass Spring diesen Teil in ihren Dokumenten nicht richtig behandelt, da es ziemlich einfach ist, sobald Sie einige Richtlinien haben. – Balazs

1

Sie haben 2 Möglichkeiten.

One ist als @Arpit erwähnt: mehrere Cachemanager definieren und es in jedem Verfahren Ebene Anmerkungen angeben (@Cacheable, @CachePut, usw.) oder auf Klassenebene Anmerkungen (@CacheConfig)

Sie auch eigene erstellen Anmerkungen:

@CacheConfig(cacheManager = "guavaCacheManager") 
@Target(value = ElementType.TYPE) 
@Retention(value = RetentionPolicy.RUNTIME) 
public @interface GuavaCacheable { 
} 

@GuavaCacheable 
@Service 
public class MyServiceImpl implements MyService { 
} 

Und als zweite Option können Sie ein benutzerdefiniertes Cache-Resolver, wenn Ihre Caching-Bedürfnisse sind komplex erstellen.

Sie können here für einen benutzerdefinierten CacheResolver anzeigen, der mehrere CacheManager verwaltet und das Aktivieren/Deaktivieren unterstützt. In den meisten Fällen ist CacheResolver jedoch übertrieben.

Verwandte Themen