Кэширование является ключом к производительности почти каждого приложения. Иногда требуется распределенное кэширование , но не всегда. Во многих случаях локальный кэш будет работать просто отлично, и нет необходимости в дополнительных затратах и сложности распределенного кэша.
Таким образом, во многих приложениях, включая обычные 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, являются их собственными. |