Einführung in Ehcache

1. Übersicht

In diesem Artikel stellen wir Ehcache vor, einen weit verbreiteten Open-Source-Java-basierten Cache. Es bietet Speicher- und Festplattenspeicher, Listener, Cache-Loader, RESTful- und SOAP-APIs und andere sehr nützliche Funktionen.

Um zu zeigen, wie das Caching unsere Anwendung optimieren kann, erstellen wir eine einfache Methode, mit der Quadratwerte der angegebenen Zahlen berechnet werden. Bei jedem Aufruf ruft die Methode die Methode berechneSquareOfNumber (int number) auf und druckt eine Informationsnachricht an die Konsole.

Mit diesem einfachen Beispiel möchten wir zeigen, dass die Berechnung der quadratischen Werte nur einmal erfolgt und jeder zweite Aufruf mit demselben Eingabewert das Ergebnis aus dem Cache zurückgibt.

Es ist wichtig zu beachten, dass wir uns ganz auf Ehcache selbst konzentrieren (ohne Frühling). Wenn Sie sehen möchten, wie Ehcache mit Spring funktioniert, lesen Sie diesen Artikel.

2. Maven-Abhängigkeiten

Um Ehcache verwenden zu können, müssen wir diese Maven-Abhängigkeit hinzufügen:

 org.ehcache ehcache 3.1.3 

Die neueste Version des Ehcache-Artefakts finden Sie hier.

3. Cache-Konfiguration

Ehcache kann auf zwei Arten konfiguriert werden:

  • Der erste Weg führt über Java POJO, wo alle Konfigurationsparameter über die Ehcache-API konfiguriert werden
  • Der zweite Weg ist die Konfiguration über eine XML-Datei, in der wir Ehcache gemäß der bereitgestellten Schemadefinition konfigurieren können

In diesem Artikel werden beide Ansätze gezeigt - Java- und XML-Konfiguration.

3.1. Java-Konfiguration

Dieser Unterabschnitt zeigt, wie einfach es ist, Ehcache mit POJOs zu konfigurieren. Außerdem erstellen wir eine Hilfsklasse, um die Konfiguration und Verfügbarkeit des Caches zu vereinfachen:

public class CacheHelper { private CacheManager cacheManager; private Cache squareNumberCache; public CacheHelper() { cacheManager = CacheManagerBuilder .newCacheManagerBuilder().build(); cacheManager.init(); squareNumberCache = cacheManager .createCache("squaredNumber", CacheConfigurationBuilder .newCacheConfigurationBuilder( Integer.class, Integer.class, ResourcePoolsBuilder.heap(10))); } public Cache getSquareNumberCacheFromCacheManager() { return cacheManager.getCache("squaredNumber", Integer.class, Integer.class); } // standard getters and setters }

Um unseren Cache zu initialisieren, müssen wir zuerst das Ehcache CacheManager- Objekt definieren . In diesem Beispiel erstellen wir einen Standard-Cache squaredNumber “ mit der API newCacheManagerBuilder () .

Der Cache ordnet Integer- Schlüssel einfach Integer- Werten zu.

Beachten Sie, dass wir das CacheManager- Objekt mit der Methode init () initialisieren müssen, bevor wir den definierten Cache verwenden.

Um unseren Cache zu erhalten, können wir einfach die getCache () - API mit den angegebenen Namen, Schlüsseln und Werttypen unseres Caches verwenden.

Mit diesen wenigen Zeilen haben wir unseren ersten Cache erstellt, der jetzt für unsere Anwendung verfügbar ist.

3.2. XML-Konfiguration

Das Konfigurationsobjekt aus Unterabschnitt 3.1. entspricht der Verwendung dieser XML-Konfiguration:

 java.lang.Integer java.lang.Integer 10 

Um diesen Cache in unsere Java-Anwendung aufzunehmen, müssen wir die XML-Konfigurationsdatei in Java lesen:

URL myUrl = getClass().getResource(xmlFile); XmlConfiguration xmlConfig = new XmlConfiguration(myUrl); CacheManager myCacheManager = CacheManagerBuilder .newCacheManager(xmlConfig);

4. Ehcache-Test

In Abschnitt 3 haben wir gezeigt, wie Sie einen einfachen Cache für Ihre Zwecke definieren können. Um zu zeigen, dass das Caching tatsächlich funktioniert, erstellen wir die SquaredCalculator- Klasse, die den Quadratwert der bereitgestellten Eingabe berechnet und den berechneten Wert in einem Cache speichert.

Wenn der Cache bereits einen berechneten Wert enthält, geben wir den zwischengespeicherten Wert zurück und vermeiden unnötige Berechnungen:

public class SquaredCalculator { private CacheHelper cache; public int getSquareValueOfNumber(int input) { if (cache.getSquareNumberCache().containsKey(input)) { return cache.getSquareNumberCache().get(input); } System.out.println("Calculating square value of " + input + " and caching result."); int squaredValue = (int) Math.pow(input, 2); cache.getSquareNumberCache().put(input, squaredValue); return squaredValue; } //standard getters and setters; }

Um unser Testszenario abzuschließen, benötigen wir auch den Code, der die Quadratwerte berechnet:

@Test public void whenCalculatingSquareValueAgain_thenCacheHasAllValues() { for (int i = 10; i < 15; i++) { assertFalse(cacheHelper.getSquareNumberCache().containsKey(i)); System.out.println("Square value of " + i + " is: " + squaredCalculator.getSquareValueOfNumber(i) + "\n"); } for (int i = 10; i < 15; i++) { assertTrue(cacheHelper.getSquareNumberCache().containsKey(i)); System.out.println("Square value of " + i + " is: " + squaredCalculator.getSquareValueOfNumber(i) + "\n"); } }

Wenn wir unseren Test ausführen, erhalten wir dieses Ergebnis in unserer Konsole:

Calculating square value of 10 and caching result. Square value of 10 is: 100 Calculating square value of 11 and caching result. Square value of 11 is: 121 Calculating square value of 12 and caching result. Square value of 12 is: 144 Calculating square value of 13 and caching result. Square value of 13 is: 169 Calculating square value of 14 and caching result. Square value of 14 is: 196 Square value of 10 is: 100 Square value of 11 is: 121 Square value of 12 is: 144 Square value of 13 is: 169 Square value of 14 is: 196

Wie Sie sehen können, führte die berechne () -Methode Berechnungen nur beim ersten Aufruf durch. Beim zweiten Aufruf wurden alle Werte im Cache gefunden und von diesem zurückgegeben.

5. Andere Ehcache-Konfigurationsoptionen

Als wir unseren Cache im vorherigen Beispiel erstellt haben, war es ein einfacher Cache ohne spezielle Optionen. In diesem Abschnitt werden andere Optionen angezeigt, die bei der Cache-Erstellung hilfreich sind.

5.1. Festplattenpersistenz

Wenn zu viele Werte zum Speichern im Cache vorhanden sind, können wir einige dieser Werte auf der Festplatte speichern.

PersistentCacheManager persistentCacheManager = CacheManagerBuilder.newCacheManagerBuilder() .with(CacheManagerBuilder.persistence(getStoragePath() + File.separator + "squaredValue")) .withCache("persistent-cache", CacheConfigurationBuilder .newCacheConfigurationBuilder(Integer.class, Integer.class, ResourcePoolsBuilder.newResourcePoolsBuilder() .heap(10, EntryUnit.ENTRIES) .disk(10, MemoryUnit.MB, true)) ) .build(true); persistentCacheManager.close();

Anstelle des Standard- CacheManagers verwenden wir jetzt den PersistentCacheManager, der alle Werte beibehält , die nicht im Speicher gespeichert werden können.

Aus der Konfiguration geht hervor, dass der Cache 10 Elemente im Speicher speichert und 10 MB auf der Festplatte für die Persistenz zuweist.

5.2. Datenablauf

Wenn wir viele Daten zwischenspeichern, speichern wir natürlich zwischengespeicherte Daten für einen bestimmten Zeitraum, um eine große Speichernutzung zu vermeiden.

Ehcache steuert die Datenaktualität über die Ablaufschnittstelle :

CacheConfiguration cacheConfiguration = CacheConfigurationBuilder .newCacheConfigurationBuilder(Integer.class, Integer.class, ResourcePoolsBuilder.heap(100)) .withExpiry(Expirations.timeToLiveExpiration(Duration.of(60, TimeUnit.SECONDS))).build();

In diesem Cache leben alle Daten 60 Sekunden lang und werden nach dieser Zeit aus dem Speicher gelöscht.

6. Fazit

In diesem Artikel haben wir gezeigt, wie einfaches Ehcache-Caching in einer Java-Anwendung verwendet wird.

In unserem Beispiel haben wir gesehen, dass selbst ein einfach konfigurierter Cache viele unnötige Vorgänge einsparen kann. Außerdem haben wir gezeigt, dass wir Caches über POJOs und XML konfigurieren können und dass Ehcache einige nette Funktionen hat - wie Persistenz und Datenablauf.

Der Code aus diesem Artikel ist wie immer auf GitHub zu finden.