1. Обзор
В этом руководстве мы узнаем, как настроить несколько менеджеров кэша в приложении Spring.
2. Кэширование
Spring применяет кэширование к методам, чтобы наше приложение не выполняло один и тот же метод несколько раз для одного и того же ввода.
Это очень легко реализовать кэширование в приложении Spring . Это можно сделать, добавив аннотацию @EnableCaching в наш класс конфигурации:
@Configuration @EnableCaching public class MultipleCacheManagerConfig {}
Затем мы можем начать кэшировать выходные данные метода, добавив аннотацию @Cacheable к методу:
@Cacheable(cacheNames = "customers") public Customer getCustomerDetail(Integer customerId) { return customerDetailRepository.getCustomerDetail(customerId); }
Как только мы добавим вышеуказанную конфигурацию, Spring Boot сама создаст для нас менеджер кэша.
По умолчанию он использует ConcurrentHashMap в качестве базового кэша, если мы явно не указали какой-либо другой .
3. Настройка Нескольких Менеджеров Кэша
В некоторых случаях нам может потребоваться использовать более одного менеджера кэша в нашем приложении. Итак, давайте посмотрим, как мы можем сделать это в нашем приложении Spring Boot на примере.
В нашем примере мы будем использовать Caffeine CacheManager и простой ConcurrentMapCacheManager .
Caffeine CacheManager предоставляется spring-boot-starter-cache starter. Он будет автоматически настроен весной, если присутствует Кофеин , который является библиотекой кэширования, написанной на Java 8.
ConcurrentMapCacheManager использует реализацию кэша с использованием C concurrenthashmap .
Мы можем сделать это следующими способами.
3.1. Использование @Primary
Мы можем создать два компонента менеджеров кэша в нашем классе конфигурации. Затем мы можем сделать один боб основным:
@Configuration @EnableCaching public class MultipleCacheManagerConfig { @Bean @Primary public CacheManager cacheManager() { CaffeineCacheManager cacheManager = new CaffeineCacheManager("customers", "orders"); cacheManager.setCaffeine(Caffeine.newBuilder() .initialCapacity(200) .maximumSize(500) .weakKeys() .recordStats()); return cacheManager; } @Bean public CacheManager alternateCacheManager() { return new ConcurrentMapCacheManager("customerOrders", "orderprice"); } }
Теперь Spring Boot будет использовать Caffeine CacheManager по умолчанию для всех методов, пока мы явно не укажем наш alternateCacheManager для метода:
@Cacheable(cacheNames = "customers") public Customer getCustomerDetail(Integer customerId) { return customerDetailRepository.getCustomerDetail(customerId); } @Cacheable(cacheNames = "customerOrders", cacheManager = "alternateCacheManager") public ListgetCustomerOrders(Integer customerId) { return customerDetailRepository.getCustomerOrders(customerId); }
В приведенном выше примере наше приложение будет использовать Caffeine CacheManager для метода getCustomerDetail () . А для метода getCustomerOrders() он будет использовать альтернативный менеджер кэша.
3.2. Расширение поддержки CachingConfigurerSupport
Другой способ сделать это-расширить класс CachingConfigurerSupport и переопределить метод cache Manager (). Этот метод возвращает компонент, который будет менеджером кэша по умолчанию для нашего приложения:
@Configuration @EnableCaching public class MultipleCacheManagerConfig extends CachingConfigurerSupport { @Bean public CacheManager cacheManager() { CaffeineCacheManager cacheManager = new CaffeineCacheManager("customers", "orders"); cacheManager.setCaffeine(Caffeine.newBuilder() .initialCapacity(200) .maximumSize(500) .weakKeys() .recordStats()); return cacheManager; } @Bean public CacheManager alternateCacheManager() { return new ConcurrentMapCacheManager("customerOrders", "orderprice"); } }
Обратите внимание, что мы все еще можем создать другой компонент под названием alternate Cache Manager. Мы можем использовать этот альтернативный менеджер кэша для метода, явно указав его, как это было в последнем примере.
3.3. Использование cacheResolver
Мы можем реализовать интерфейс Cache Resolver и создать пользовательский Cache Resolver :
public class MultipleCacheResolver implements CacheResolver { private final CacheManager simpleCacheManager; private final CacheManager caffeineCacheManager; private static final String ORDER_CACHE = "orders"; private static final String ORDER_PRICE_CACHE = "orderprice"; public MultipleCacheResolver(CacheManager simpleCacheManager,CacheManager caffeineCacheManager) { this.simpleCacheManager = simpleCacheManager; this.caffeineCacheManager=caffeineCacheManager; } @Override public Collection extends Cache> resolveCaches(CacheOperationInvocationContext> context) { Collectioncaches = new ArrayList (); if ("getOrderDetail".equals(context.getMethod().getName())) { caches.add(caffeineCacheManager.getCache(ORDER_CACHE)); } else { caches.add(simpleCacheManager.getCache(ORDER_PRICE_CACHE)); } return caches; } }
В этом случае мы должны переопределить метод resolver Caches интерфейса Cache Resolver .
В нашем примере мы выбираем менеджер кэша на основе имени метода. После этого нам нужно создать компонент нашего пользовательского Распознавателя кэша :
@Configuration @EnableCaching public class MultipleCacheManagerConfig extends CachingConfigurerSupport { @Bean public CacheManager cacheManager() { CaffeineCacheManager cacheManager = new CaffeineCacheManager("customers", "orders"); cacheManager.setCaffeine(Caffeine.newBuilder() .initialCapacity(200) .maximumSize(500) .weakKeys() .recordStats()); return cacheManager; } @Bean public CacheManager alternateCacheManager() { return new ConcurrentMapCacheManager("customerOrders", "orderprice"); } @Bean public CacheResolver cacheResolver() { return new MultipleCacheResolver(alternateCacheManager(), cacheManager()); } }
Теперь мы можем использовать наш пользовательский Распознаватель кэша для разрешения диспетчера кэша для наших методов:
@Component public class OrderDetailBO { @Autowired private OrderDetailRepository orderDetailRepository; @Cacheable(cacheNames = "orders", cacheResolver = "cacheResolver") public Order getOrderDetail(Integer orderId) { return orderDetailRepository.getOrderDetail(orderId); } @Cacheable(cacheNames = "orderprice", cacheResolver = "cacheResolver") public double getOrderPrice(Integer orderId) { return orderDetailRepository.getOrderPrice(orderId); } }
Здесь мы передаем имя нашего компонента Cache Resolver в элементе cache Resolver .
4. Заключение
В этой статье мы узнали, как включить кэширование в нашем приложении Spring Boot. Затем мы узнали три способа, с помощью которых мы можем использовать несколько менеджеров кэша в нашем приложении.
Как всегда, код для этих примеров доступен на GitHub .