咖啡因缓存刷新/重新加载缓存手动或按需

时间:2018-03-01 13:43:49

标签: caching caffeine

我在我的应用程序中实现了咖啡因缓存。我正在缓存几个静态表中的数据。但我想知道我是否可以手动或按需使用REST API或任何其他方式刷新/清除/重新加载缓存。 任何人都可以建议一种方法来实现这样的要求。

我想要的东西: - 端点网址如: - http://localhost:8080/refreshCache

这将在内部触发一些方法并清除缓存或手动重新加载缓存中的新值。

以下是缓存配置:

@Configuration
public class CacheConfig{

     private com.github.benmanes.caffeine.cache.Cache<Object, Object> cache;

    @Bean
    Caffeine<Object,Object> cacheBuilder(){
        return Caffeine.newBuilder()
                .initialCapacity(300)
                .maximumSize(50000)
                .expireAfterAccess(1, TimeUnit.DAYS)
                .removalListener(new CacheRemovalListener())
                .recordStats();
    }

    class CacheRemovalListener implements RemovalListener<Object, Object> {
        @Override
        public void onRemoval(Object key, Object value, RemovalCause cause) {
            System.out.format("Removal listener called with key [%s], cause[%s], evicted [%s] %n", 
                    key , cause.toString(), cause.wasEvicted());
        }
    }

} 

1 个答案:

答案 0 :(得分:1)

您可以使用Spring的CacheManager创建CaffeineCache实例,然后可以使用CacheManager在任何缓存上执行CRUD操作。

请参见下面的代码。

Bean配置:

public class CacheBeansConfig {

  @Bean
  public CacheManager cacheManager() {
    // create multiple instances of cache
    CaffeineCacheManager cacheManager = new CaffeineCacheManager("UserCache","InventoryCache");
    cacheManager.setCaffeine(caffeineCacheBuilder());
    return cacheManager;
  }

  private Caffeine<Object, Object> caffeineCacheBuilder() {

    return Caffeine.newBuilder()
        .initialCapacity(<initial capacity>)
        .maximumSize(<max size>)
        .expireAfterAccess(<expire after hrs>, TimeUnit.HOURS)
        .recordStats();
  }

这将使用两个Caffeeine Cache实例初始化CacheManager。

使用下面的Rest Controller类访问这些类。

@RestController
@RequestMapping(path = "/v1/admin/cache")
public class ACSCacheAdminController {

  @Autowired
  private CacheManager cacheManager;

  /**
   * call this to invalidate all cache instances
   */
  @DeleteMapping(
      path = "/",
      produces = {"application/json"})
  public void invalidateAll() {
    Collection<String> cacheNames = cacheManager.getCacheNames();
    cacheNames.forEach(this::getCacheAndClear);
  }

  /**
   * call this to invalidate a given cache name
   */
  @DeleteMapping(
      path = "/{cacheName}",
      produces = {"application/json"})
  public void invalidateCache(@PathVariable("cacheName") final String cacheName) {
    getCacheAndClear(cacheName);
  }

  /**
   * Use this to refresh a cache instance
   */
  @PostMapping(
      path = "/{cacheName}",
      produces = {"application/json"})
  public void invalidateCache(@PathVariable("cacheName") final String cacheName) {
    getCacheAndClear(cacheName);
    Cache cache = cacheManager.getCache(cacheName);
    // your logic to put in above cache instance
    // use cache.put(key,value)
  }


  /**
   * call this to invalidate cache entry by given cache name and cache key
   */
  @DeleteMapping(
      path = "/{cacheName}/{key}/",
      produces = {"application/json"})
  public void invalidateCacheKey(
      @PathVariable("cacheName") final String cacheName, @PathVariable("key") Object key) {
    final Cache cache = cacheManager.getCache(cacheName);
    if (cache == null) {
      throw new IllegalArgumentException("invalid cache name for key invalidation: " + cacheName);
    }
    cache.evict(key);
  }

  @GetMapping(
      path = "/{cacheName}/{key}",
      produces = {"application/json"})
  public ResponseEntity<Object> getByCacheNameAndKey(
      @PathVariable("cacheName") final String cacheName, @PathVariable("key") final int key) {
    final Cache cache = cacheManager.getCache(cacheName);
    if (cache == null) {
      throw new IllegalArgumentException("invalid cache name: " + cacheName);
    }
    return ResponseEntity.ok().body(cache.get(key));
  }

  private void getCacheAndClear(final String cacheName) {

    final Cache cache = cacheManager.getCache(cacheName);
    if (cache == null) {
      throw new IllegalArgumentException("invalid cache name: " + cacheName);
    }
    cache.clear();
  }

只需根据您的需要更改代码:)