Einführung in Ehcache
1. Überblick
In diesem Artikel stellen wirEhcache vor, einen weit verbreiteten Open-Source-Java-basierten Cache. Es bietet Speicher- und Plattenspeicher, Listener, Cache Loader, RESTful- und SOAP-APIs und andere sehr nützliche Funktionen.
Um zu zeigen, wie 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 voncalculateSquareOfNumber(int number)auf und druckt eine Informationsnachricht an die Konsole.
Mit diesem einfachen Beispiel möchten wir zeigen, dass die Berechnung der quadrierten Werte nur einmal durchgeführt wird und jeder zweite Aufruf mit demselben Eingabewert ein Ergebnis aus dem Cache zurückgibt.
Es ist wichtig zu beachten, dass wir uns ausschließlich auf Ehcache selbst konzentrieren (ohne Frühling). Wenn Sie sehen möchten, wie Ehcache mit Spring funktioniert, lesen Sie readthis article.
2. Maven-Abhängigkeiten
Um Ehcache nutzen zu können, müssen wir diese Maven-Abhängigkeit hinzufügen:
org.ehcache
ehcache
3.1.3
Die neueste Version des Ehcache-Artefakts befindet sich inhere.
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äßprovided schema definition 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 für eine einfachere Cache-Konfiguration und -Verfügbarkeit:
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 Objekt von EhcacheCacheManagerdefinieren. In diesem Beispiel erstellen wir einen StandardcachesquaredNumber” mit der API. vonnewCacheManagerBuilder()
Der Cache ordnet einfach die Schlüssel vonIntegerden Werten vonIntegerzu.
Beachten Sie, dass wir dasCacheManager-Objekt mit derinit()-Methode initialisieren müssen, bevor wir den definierten Cache verwenden.
Um unseren Cache zu erhalten, können wir einfach diegetCache()-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. Wir haben 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 KlasseSquaredCalculator, 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 natürlich einen 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 quadratische Werte 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 Methode voncalculate()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 einige dieser Werte auf der Festplatte gespeichert werden.
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 von StandardCacheManager verwenden wir jetztPersistentCacheManager, wodurch alle Werte beibehalten werden, die nicht im Speicher gespeichert werden können.
Aus der Konfiguration können wir ersehen, dass der Cache 10 Elemente im Speicher speichert und 10 MB auf der Festplatte für die Persistenz reserviert.
5.2. Datenablauf
Wenn wir viele Daten zwischenspeichern, speichern wir natürlich zwischengespeicherte Daten für einen bestimmten Zeitraum, um eine hohe Speichernutzung zu vermeiden.
Ehcache steuert die Datenaktualität über die Schnittstelle vonExpiry:
CacheConfiguration cacheConfiguration
= CacheConfigurationBuilder
.newCacheConfigurationBuilder(Integer.class, Integer.class,
ResourcePoolsBuilder.heap(100))
.withExpiry(Expirations.timeToLiveExpiration(Duration.of(60,
TimeUnit.SECONDS))).build();
In diesem Cache werden alle Daten 60 Sekunden lang gespeichert und nach Ablauf dieses Zeitraums aus dem Speicher gelöscht.
6. Fazit
In diesem Artikel wurde 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 Operationen 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.
Wie immer kann der Code aus diesem Artikelon GitHub gefunden werden.