知識庫 / Spring RSS 訂閱

使用 Spring 中的多個緩存管理器

Spring
HongKong
3
01:00 PM · Dec 06 ,2025

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 應用程序中實現這一點。

在我們的示例中,我們將使用一個 CaffeineCacheManager 和一個簡單的 ConcurrentMapCacheManager

CaffeineCacheManagerspring-boot-starter-cache 啓動器提供。 如果存在 Caffeine(一種 Java 8 中編寫的緩存庫),則 Spring 會自動配置它。

ConcurrentMapCacheManager 使用 ConcurrentHashMap 實現緩存。

我們可以通過以下方式實現。

3.1. 使用 @Primary

我們可以創建配置類中兩個緩存管理器 Bean。然後,我們可以將其中一個 Bean 設置為主 Bean:

@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 將在所有方法中使用 CaffeineCacheManager 作為默認緩存管理器,直到我們明確指定某個方法的 alternateCacheManager

@Cacheable(cacheNames = "customers")
public Customer getCustomerDetail(Integer customerId) {
    return customerDetailRepository.getCustomerDetail(customerId);
}

@Cacheable(cacheNames = "customerOrders", cacheManager = "alternateCacheManager")
public List<Order> getCustomerOrders(Integer customerId) {
    return customerDetailRepository.getCustomerOrders(customerId);
}

在上述示例中,我們的應用程序將使用 CaffeineCacheManager 來處理 getCustomerDetail() 方法。對於 getCustomerOrders() 方法,它將使用 alternateCacheManager。

3.2. 擴展 CachingConfigurerSupport

另一種實現方式是擴展 CachingConfigurerSupport 類,並重寫 cacheManager() 方法。該方法返回一個 Bean,它將作為我們應用程序的默認緩存管理器:

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

請注意,我們仍然可以創建另一個名為 alternateCacheManager 的 Bean。我們可以通過顯式指定它來使用這個 alternateCacheManager,就像在之前的示例中那樣。

3.3. 使用 CacheResolver 接口

我們可以實現 CacheResolver 接口並創建自定義的 CacheResolver

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) {
        Collection<Cache> caches = new ArrayList<Cache>();
        if ("getOrderDetail".equals(context.getMethod().getName())) {
            caches.add(caffeineCacheManager.getCache(ORDER_CACHE));
        } else {
            caches.add(simpleCacheManager.getCache(ORDER_PRICE_CACHE));
        }
        return caches;
    }
}

在這種情況下,我們需要覆蓋 CacheResolver 接口中的 resolveCaches 方法。

在我們的示例中,我們通過方法名來選擇緩存管理器。之後,我們需要創建一個自定義的 CacheResolver Bean:

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

現在我們可以使用我們自定義的 CacheResolver 來為我們的方法解決緩存管理器:

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

在這裏,我們通過將 CacheResolver Bean 傳遞到 cacheResolver 元素中。

4. 結論

在本文中,我們學習瞭如何啓用 Spring Boot 應用程序中的緩存。此外,我們還學習了通過三種方式在應用程序中使用多個緩存管理器。

user avatar
0 位用戶收藏了這個故事!
收藏

發佈 評論

Some HTML is okay.