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

Использование нескольких менеджеров кэша весной

Узнайте, как мы можем включить несколько менеджеров кэша в нашем приложении Spring Boot.

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

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 List getCustomerOrders(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 resolveCaches(CacheOperationInvocationContext context) {
        Collection caches = 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 .