Einführung in Ehcache

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.