Кэширование является ключом к производительности почти каждого приложения. Иногда требуется распределенное кэширование , но не всегда. Во многих случаях локальный кэш будет работать просто отлично, и нет необходимости в дополнительных затратах и сложности распределенного кэша.
Таким образом, во многих приложениях, включая обычные Spring и Spring Boot, вы можете использовать @Cacheable для любого метода, и его результат будет кэшироваться, чтобы при следующем вызове метода возвращался кэшированный результат.
Spring имеет некоторые реализации менеджера кэша по умолчанию, но внешние библиотеки всегда лучше и более гибки, чем простые реализации. Например, Caffeine — это высокопроизводительная библиотека кеша Java . А Spring Boot поставляется с CaffeineCacheManager . Итак, в идеале, это все, что вам нужно — вы просто создаете компонент управления кэшем и у вас есть кэширование для ваших аннотированных методов @Cacheable .
Однако предоставленный менеджер кэша позволяет вам настроить только одну спецификацию кэша. Спецификации кэша включают время истечения, начальную емкость, максимальный размер и т. Д. Таким образом, все ваши кэши в этом менеджере кэша будут создаваться с одной спецификацией кэша. Менеджер кэша поддерживает список предопределенных кэшей, а также динамически создаваемых кэшей, но в обоих случаях используется одна спецификация кэша. И это редко полезно для производства. Как правило, со встроенными кеш-менеджерами нужно быть осторожным .
Есть несколько блогов , в которых рассказывается, как определять пользовательские кэши с помощью пользовательских спецификаций. Однако эти параметры не поддерживают динамический сценарий использования спецификации кэша по умолчанию, который поддерживает встроенный менеджер. В идеале вы должны иметь возможность использовать любое имя в @Cacheable и автоматически должен создаваться кеш с некоторыми спецификациями по умолчанию, но у вас также должна быть возможность переопределить это для определенных кешей.
Вот почему я решил использовать более простой подход, чем определение всех кэшей в коде, что обеспечивает большую гибкость. Он расширяет CaffeineCacheManager для обеспечения этой функциональности:
|
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
|
/** * Extending Caffeine cache manager to allow flexible per-cache configuration */public class FlexibleCaffeineCacheManager extends CaffeineCacheManager implements InitializingBean { private Map<String, String> cacheSpecs = new HashMap<>(); private Map<String, Caffeine<Object, Object>> builders = new HashMap<>(); private CacheLoader cacheLoader; @Override public void afterPropertiesSet() throws Exception { for (Map.Entry<String, String> cacheSpecEntry : cacheSpecs.entrySet()) { builders.put(cacheSpecEntry.getKey(), Caffeine.from(cacheSpecEntry.getValue())); } } @Override @SuppressWarnings("unchecked") protected Cache<Object, Object> createNativeCaffeineCache(String name) { Caffeine<Object, Object> builder = builders.get(name); if (builder == null) { return super.createNativeCaffeineCache(name); } if (this.cacheLoader != null) { return builder.build(this.cacheLoader); } else { return builder.build(); } } public Map<String, String> getCacheSpecs() { return cacheSpecs; } public void setCacheSpecs(Map<String, String> cacheSpecs) { this.cacheSpecs = cacheSpecs; } public void setCacheLoader(CacheLoader cacheLoader) { super.setCacheLoader(cacheLoader); this.cacheLoader = cacheLoader; }} |
Короче говоря, он создает один компоновщик кофеина для каждой спецификации и использует его вместо компоновщика по умолчанию, когда требуется новый кеш.
Тогда пример конфигурации XML будет выглядеть так:
|
1
2
3
4
5
6
7
8
|
<bean id="cacheManager" class="net.bozho.util.FlexibleCaffeineCacheManager"> <property name="cacheSpecification" value="expireAfterWrite=10m"/> <property name="cacheSpecs"> <map> <entry key="statistics" value="expireAfterWrite=1h"/> </map> </property></bean> |
С настройкой Java это довольно просто — вы просто устанавливаете карту cacheSpecs .
Хотя Spring уже превратился в огромный фреймворк, который предоставляет всевозможные функции, он не отказался от принципов расширяемости.
Расширение встроенных каркасных классов — это то, что происходит довольно часто, и это должно быть в каждом наборе инструментов. Эти классы создаются с учетом расширения — вы заметите, что многие методы в CaffeineCacheManager protected . Поэтому мы должны использовать это всякий раз, когда это необходимо.
|
Опубликовано на Java Code Geeks с разрешения Божидара Божанова, партнера нашей программы JCG . См. Оригинальную статью здесь: несколько конфигураций кэша с кофеином и весенней загрузкой. Мнения, высказанные участниками Java Code Geeks, являются их собственными. |