Рубрики
Без рубрики

Введение В Ehcache

Краткое и практическое руководство по Ehcache с приложением Java

Автор оригинала: baeldung.

1. Обзор

В этой статье мы представим Ehcache , широко используемый кэш на основе Java с открытым исходным кодом. Он включает в себя хранилища памяти и дисков, прослушиватели, загрузчики кэша, API RESTful и SOAP и другие очень полезные функции.

Чтобы показать, как кэширование может оптимизировать наше приложение, мы создадим простой метод, который будет вычислять квадратные значения предоставленных чисел. При каждом вызове метод будет вызывать вычислять квадрат числа(int number) метод и выводить информационное сообщение на консоль.

На этом простом примере мы хотим показать, что вычисление квадратов значений выполняется только один раз, и каждый второй вызов с тем же входным значением возвращает результат из кэша.

Важно отметить, что мы полностью сосредоточены на самом Ehcache (без Spring); если вы хотите увидеть, как Ehcache работает с Spring, ознакомьтесь с этой статьей .

2. Зависимости Maven

Чтобы использовать Ehcache, нам нужно добавить эту зависимость Maven:


    org.ehcache
    ehcache
    3.1.3

Последнюю версию артефакта Ehcache можно найти здесь .

3. Конфигурация кэша

Ehcache можно настроить двумя способами:

  • Первый способ-через Java POJO, где все параметры конфигурации настраиваются через API Ehcache
  • Второй способ-это настройка через XML-файл, где мы можем настроить Ehcache в соответствии с предоставленным определением схемы

В этой статье мы покажем оба подхода – Java, а также конфигурацию XML.

3.1. Конфигурация Java

В этом подразделе будет показано, как легко настроить Ehcache с помощью POJOs. Кроме того, мы создадим вспомогательный класс для упрощения настройки и доступности кэша:

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
}

Чтобы инициализировать наш кэш, сначала нам нужно определить объект Ehcache CacheManager . В этом примере мы создаем кэш по умолчанию квадратное число” с помощью new CacheManagerBuilder() API .

Кэш просто сопоставит Integer ключи с Integer значениями.

Обратите внимание, что перед началом использования определенного кэша нам необходимо инициализировать объект Cache Manager с помощью метода init () .

Наконец, чтобы получить наш кэш, мы можем просто использовать getCache() API с предоставленными типами имен, ключей и значений нашего кэша.

С помощью этих нескольких строк мы создали наш первый кэш, который теперь доступен для нашего приложения.

3.2. Конфигурация XML

Объект конфигурации из подраздела 3.1. равен использованию этой конфигурации XML:


    java.lang.Integer
    java.lang.Integer
    10

И чтобы включить этот кэш в наше Java-приложение, нам нужно прочитать файл конфигурации XML в Java:

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

4. Тест Ehcache

В разделе 3. мы показали, как вы можете определить простой кэш для своих целей. Чтобы показать, что кэширование действительно работает, мы создадим класс Squared Calculator , который вычислит квадратное значение предоставленных входных данных и сохранит вычисленное значение в кэше.

Конечно, если кэш уже содержит вычисленное значение, мы вернем кэшированное значение и избежим ненужных вычислений:

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;
}

Для завершения нашего тестового сценария нам также понадобится код, который будет вычислять квадратные значения:

@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");
    }
}

Если мы запустим наш тест, мы получим этот результат в нашей консоли:

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

Как вы можете заметить, метод calculate() выполнял вычисления только при первом вызове. При втором вызове все значения были найдены в кэше и возвращены из него.

5. Другие Параметры Конфигурации Ehcache

Когда мы создавали наш кэш в предыдущем примере, это был простой кэш без каких-либо специальных опций. В этом разделе будут показаны другие параметры, которые полезны при создании кэша.

5.1. Сохраняемость диска

Если в кэше слишком много значений для хранения, мы можем сохранить некоторые из этих значений на жестком диске.

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();

Вместо стандартного CacheManager теперь мы используем PersistentCacheManager , который сохранит все значения, которые не могут быть сохранены в памяти.

Из конфигурации мы видим, что кэш сохранит 10 элементов в памяти и выделит 10 МБ на жестком диске для сохранения.

5.2. Истечение срока действия данных

Если мы кэшируем много данных, естественно, что мы сохраняем кэшированные данные в течение некоторого периода времени, чтобы избежать большого использования памяти.

Ehcache контролирует свежесть данных через Истечение срока действия интерфейс:

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

В этом кэше все данные будут жить в течение 60 секунд, и по истечении этого периода времени они будут удалены из памяти.

6. Заключение

В этой статье мы показали, как использовать простое кэширование Ehcache в Java-приложении.

В нашем примере мы видели, что даже просто настроенный кэш может сэкономить много ненужных операций. Кроме того, мы показали, что мы можем настраивать кэши с помощью POJOs и XML, и что Ehcache имеет довольно приятные функции, такие как сохранение и истечение срока действия данных.

Как всегда, код из этой статьи можно найти на GitHub .