Eine Anleitung zum Zwischenspeichern im Frühling

Eine Anleitung zum Zwischenspeichern im Frühjahr

1. Die Cache-Abstraktion?

In diesem Artikel zeigen wir Ihnen, wie Sieuse the Caching Abstraction in Spring erreichen - und im Allgemeinen die Leistung Ihres Systems verbessern.

Wir werden das einfache Caching für einige Beispiele aus der Praxis aktivieren und diskutieren, wie wir die Leistung dieser Aufrufe durch intelligentes Cache-Management praktisch verbessern können.

Weitere Lektüre:

Spring Boot Ehcache Beispiel

Eine schnelle und praktische Anleitung zur Verwendung von Spring mit Ehcache.

Read more

Cache-Räumung in Spring Boot

Erfahren Sie, wie Sie Caches mit Spring Boot ungültig machen.

Read more

2. Anfangen

Die von Spring bereitgestellte Kern-Caching-Abstraktion befindet sich imspring-context -Smodul. Wenn Sie also Maven verwenden, sollten unserepom.xml die folgende Abhängigkeit enthalten:


    org.springframework
    spring-context
    5.1.8.RELEASE

Interessanterweise gibt es ein anderes Modul mit dem Namenspring-context-support,, das über demspring-context -Schmelz sitzt und einige weitereCacheManagers bereitstellt, die vonEhCache oderCaffeine unterstützt werden. Wenn Sie diese als Cache-Speicher verwenden möchten, verwenden Sie stattdessen den Smodulespring-context-support :


    org.springframework
    spring-context-support
    5.1.8.RELEASE

Da dasspring-context-support-Modul transitiv vomspring-context -Schmelz abhängt, ist für diespring-context. keine separate Abhängigkeitsdeklaration erforderlich

2.1. Spring Boot

Wenn Sie ein Spring Boot-Benutzer sind, verwenden Sie dasspring-boot-starter-cache starter-Paket, um die Caching-Abhängigkeiten einfach hinzuzufügen:


    org.springframework.boot
    spring-boot-starter-cache

Unter die Haube bringt der Starter dasspring-context-support module.

3. Caching aktivieren

Um das Zwischenspeichern zu ermöglichen, verwendet Spring Anmerkungen wie jedes andere Feature auf Konfigurationsebene im Framework.

Die Caching-Funktion kann deklarativ aktiviert werden, indem einfach die Annotation@EnableCachingzu einer der Konfigurationsklassen hinzugefügt wird:

@Configuration
@EnableCaching
public class CachingConfig {

    @Bean
    public CacheManager cacheManager() {
        return new ConcurrentMapCacheManager("addresses");
    }
}

Sie können natürlich auchenable cache management with XMLkonfigurieren:


    

    
        
            
                
            
        
    

Note: Nachdem wir das Caching aktiviert haben - für das minimale Setup - registrieren wirmust eincacheManager.

Using XML does enable more flexible options zum Konfigurieren des Cachings - Sie können Ihren eigenen Cache-Manager, Cache-Resolver und Fehlerbehandler angeben und im Allgemeinen erweiterte Anpassungsoptionen verwenden (refer to the Javadoc für weitere Details).

3.1. Spring Boot

Bei Verwendung von Spring Boot würde das bloße Vorhandensein des Starterpakets im Klassenpfad neben derEnableCaching -Sannotation dasselbeConcurrentMapCacheManager. So registrieren. Es ist keine separate Bean-Deklaration erforderlich.

Wir können auch dieauto-configuredCacheManager anpassen, die eine oder mehrereCacheManagerCustomizer<T> beans enthalten:

@Component
public class SimpleCacheCustomizer
  implements CacheManagerCustomizer {

    @Override
    public void customize(ConcurrentMapCacheManager cacheManager) {
        cacheManager.setCacheNames(asList("users", "transactions"));
    }
}

DieCacheAutoConfiguration auto-Konfiguration greift diese Customizer auf und wendet sie vor ihrer vollständigen Initialisierung auf das aktuelleCacheManager an.

4. Verwenden Sie Caching mit Anmerkungen

Sobald Sie das Caching aktiviert haben, müssen Sie das Caching-Verhalten mit deklarativen Anmerkungen an die Methoden binden.

4.1. @Cacheable

Die einfachste Möglichkeit, das Caching-Verhalten für eine Methode zu aktivieren, besteht darin, sie mit@Cacheable abzugrenzen und mit dem Namen des Caches zu parametrisieren, in dem die Ergebnisse gespeichert werden sollen:

@Cacheable("addresses")
public String getAddress(Customer customer) {...}

Der Aufruf vongetAddress() überprüft zuerst den Cacheaddresses, bevor die Methode tatsächlich aufgerufen und dann das Ergebnis zwischengespeichert wird.

Während in den meisten Fällen ein Cache ausreicht, unterstützt das Spring-Framework auch mehrere Caches, die als Parameter übergeben werden:

@Cacheable({"addresses", "directory"})
public String getAddress(Customer customer) {...}

____ Wenn in diesem Fall einer der Caches das erforderliche Ergebnis enthält, wird das Ergebnis zurückgegeben und die Methode nicht aufgerufen.

4.2. @CacheEvict __

Was wäre nun das Problem, wenn alle Methoden@Cacheable gemacht würden?

Das Problem ist Größe -we don’t want to populate the cache with values that we don’t need often. Caches können sehr groß werden, sehr schnell, und wir können an einer Menge veralteter oder nicht verwendeter Daten festhalten.

Die Annotation@CacheEvict wird verwendet, um das Entfernen eines oder mehrerer / aller Werte anzuzeigen, damit neue Werte erneut in den Cache geladen werden können:

@CacheEvict(value="addresses", allEntries=true)
public String getAddress(Customer customer) {...}

Hier verwenden wir den zusätzlichen ParameterallEntries in Verbindung mit dem zu entleerenden Cache, um alle Einträge im Cacheaddresses zu löschen und für neue Daten vorzubereiten.

__ 4.3. @CachePut

Während@CacheEvict den Aufwand für das Nachschlagen von Einträgen in einem großen Cache reduziert, indem veraltete und nicht verwendete Einträge entfernt werden, möchten Sie im Idealfallavoid evicting too much data out of the cache.

Stattdessen möchten Sie die Einträge bei jeder Änderung selektiv und intelligent aktualisieren.

Mit der Annotation@CachePut können Sie den Inhalt des Caches aktualisieren, ohne die Methodenausführung zu beeinträchtigen. Das heißt, die Methode würde immer ausgeführt und das Ergebnis zwischengespeichert.

@CachePut(value="addresses")
public String getAddress(Customer customer) {...}

Der Unterschied zwischen@Cacheable und@CachePut besteht darin, dass@Cacheableskip running the method wird, während@CachePutactually run the method wird und dann seine Ergebnisse in den Cache legt.

4.4. @Caching

Was ist, wenn Sie mehrere Annotationen desselben Typs zum Zwischenspeichern einer Methode verwenden möchten? Schauen Sie sich das falsche Beispiel unten an:

@CacheEvict("addresses")
@CacheEvict(value="directory", key=customer.name)
public String getAddress(Customer customer) {...}

Der obige Code kann nicht kompiliert werden, da Java nicht zulässt, dass mehrere Annotationen desselben Typs für eine bestimmte Methode deklariert werden.

Die Problemumgehung für das oben genannte Problem wäre:

@Caching(evict = {
  @CacheEvict("addresses"),
  @CacheEvict(value="directory", key="#customer.name") })
public String getAddress(Customer customer) {...}

Wie im obigen Code-Snippet gezeigt, können Siegroup multiple caching annotations mit@Caching verwenden und damit Ihre eigene angepasste Caching-Logik implementieren.

4.5. @CacheConfig

Mit der Annotation@CacheConfig können Siestreamline some of the cache configuration into a single place – at the class level - damit Sie die Dinge nicht mehrmals deklarieren müssen:

@CacheConfig(cacheNames={"addresses"})
public class CustomerDataService {

    @Cacheable
    public String getAddress(Customer customer) {...}

5. Bedingtes Caching

Manchmal funktioniert das Zwischenspeichern für eine Methode möglicherweise nicht in allen Situationen.

Wenn Sie beispielsweise unser Beispiel aus der Annotation@CachePutwiederverwenden, wird sowohl die Methode ausgeführt als auch die Ergebnisse jedes Mal zwischengespeichert:

@CachePut(value="addresses")
public String getAddress(Customer customer) {...}

5.1. Bedingungsparameter

Wenn wir nun mehr Kontrolle darüber haben möchten, wann die Annotation aktiv ist, können@CachePut mit einem Bedingungsparameter parametrisiert werden, der einen SpEL-Ausdruck verwendet, um sicherzustellen, dass die Ergebnisse basierend auf der Auswertung dieses Ausdrucks zwischengespeichert werden:

@CachePut(value="addresses", condition="#customer.name=='Tom'")
public String getAddress(Customer customer) {...}

5.2. Es sei denn, Parameter

Wir können auch das Caching vonbased on the output of the method rather than the input steuern - über den Parameterunless:

@CachePut(value="addresses", unless="#result.length()<64")
public String getAddress(Customer customer) {...}

Die obige Anmerkung würde Adressen zwischenspeichern, sofern sie nicht kürzer als 64 Zeichen sind.

Es ist wichtig zu wissen, dass die Parametercondition undunless in Verbindung mit allen Caching-Annotationen verwendet werden können.

Diese Art der bedingten Zwischenspeicherung kann sich als nützlich erweisen, um große Ergebnisse zu verwalten und das Verhalten basierend auf Eingabeparametern anzupassen, anstatt ein generisches Verhalten für alle Vorgänge zu erzwingen.

6. Deklaratives XML-basiertes Caching

Wenn Sie keinen Zugriff auf den Quellcode Ihrer Anwendung haben oder das Caching-Verhalten extern einspeisen möchten, können Sie auch deklaratives XML-basiertes Caching verwenden.

Hier ist unsere XML-Konfiguration: