Как выполнить итерацию по записям кэша

#java #spring #ehcache

#java #весна #кэширование #ehcache

Вопрос:

Я использую Spring3.1 в автономной среде. Я кэширую свою запись, используя аннотацию @Cachable.

Иногда мне нужно выполнить итерацию по списку кэширования, чтобы получить определенное значение (не ключ).

Итак, мне удалось получить кэшированный список, но как я мог выполнить итерацию по его элементам.

 private ClientDTO getClientDTOByClientId(Integer clientId)
{

    Cache clientCache = null;
    try
    {
        clientCache = ehCacheCacheManager.getCache("client");

          //need here to iterate on clientCache. how?


    }
    catch (Exception e)
    {
        log.error("Couldnt retrieve client from cache. clientId="   clientId);
    }
    return clientDTO;
}
 

Я использую механизм ehcache.

 <bean id="cacheManager" class="org.springframework.cache.ehcache.EhCacheCacheManager"
        p:cache-manager-ref="ehcache" />

    <bean id="ehcache"
        class="org.springframework.cache.ehcache.EhCacheManagerFactoryBean"
        p:config-location="classpath:ehcache.xml" />
 

спасибо,
Рэй.

Ответ №1:

CacheManager.getCache() возвращает net.sf.ehcache.Cache, в котором есть метод getKeys(), который возвращает список ключей кэша, которые вы можете перебирать. Для извлечения фактического объекта, который был сохранен (в отличие от обернутого net.sf.ehcache.Элемент), используйте Element.getObjectValue().

РЕДАКТИРОВАТЬ: согласно Spring, не похоже, что они когда-либо будут поддерживать Cache.getKeys() , поэтому вам придется обратиться к базовому поставщику.

Что-то вроде этого:

 public boolean contains(String cacheName, Object o) {
  net.sf.ehcache.EhCache cache = (net.sf.ehcache.EhCache) org.springframework.cache.CacheManager.getCache(cacheName).getNativeCache();
  for (Object key: cache.getKeys()) {
    Element element = cache.get(key);
    if (element != null amp;amp; element.getObjectValue().equals(o)) {
      return true;
    }
  }
  return false;
}
 

Комментарии:

1. Но у меня нет метода cache.getKeys(). Я использую org.springframework.cache. Кэш

2. Вы нашли какое-либо решение? Как выполнить итерацию по кешу infinispan. Мне нужны ключи.

3. Вы выполнили приведение к базовому поставщику?

4. В этом ответе предполагается, что унаследованный объект типа кэша имеет метод getKeys. Это не всегда верно, и один из таких кешей, как упоминалось выше, org.springframework.cache. Кэш не включает это.

5. Получение class org.springframework.cache.ehcache.EhCacheCache cannot be cast to class net.sf.ehcache.Ehcache

Ответ №2:

Другое решение, приведение org.springframework.cache .Кэшировать в javax.cache.Кэшируйте с помощью метода getNativeCache() и используйте java-итератор в качестве javax.cache.Кэш уже расширяет Iterable<Cache .Запись<K, V>> .

для получения более подробной информации прочитайте javax.cache.Кэшировать javadoc

     Cache cache = (Cache) cacheManager.getCache("yourCacheName").getNativeCache();
    Iterator<Cache.Entry> iterator = cache.iterator();

    while (iterator.hasNext()) {
        String key = (String) iterator.next().getKey();
        System.out.println(key);
    }
 

Ответ №3:

Приведенный ниже метод предоставит набор ключей кэшированных объектов, но здесь, если вы добавите свой кеш с ключами, его будет легко получить (если вы добавите непосредственно список объектов в кеш, это не сработает).

Кроме того, я использовал GuavaCache в диспетчере кэша, как показано ниже.

 @Bean
public CacheManager cacheManager() {
    SimpleCacheManager simpleCacheManager = new SimpleCacheManager();

    GuavaCache userLabCache = new GuavaCache("yourCacheName",
            CacheBuilder.newBuilder().expireAfterAccess(5, TimeUnit.MINUTES).build());
    simpleCacheManager.setCaches(Arrays.asList(userLabCache));
    return simpleCacheManager;
}
 

Затем он вернет список ключей в виде объектов, затем вы получите ключи, и вы сможете перебирать ключи и получать объекты один за другим из кэша.

Autowire Springboot CacheManager в вашем классе

 @Autowired
CacheManager cacheManager;
 

ниже приведен код для получения всех ключей.

 public Set<Object> getAllCachedUserLabKeys() {
    Set<Object> keys = null;
    try {
        GuavaCache cache = (GuavaCache) cacheManager.getCache("yourCacheName");
        if (cache != null) {
            ConcurrentMap<Object, Object> cachedMap = cache.getNativeCache().asMap();
            keys = cachedMap.keySet();
        }
    } catch (Exception e) {
        LOGGER.error("Unknown exception occured while fetchting all cached User Labs..!", e);
    }
    return keys;
}
 

Ответ №4:

Я использую это

первая конечная точка сообщит вам, какие у вас есть кеши

вторая конечная точка предоставит вам все записи для определенного кэша (с безопасным сопоставлением)

третья конечная точка предоставит вам все записи для всех ваших кэшей (с безопасным сопоставлением)

 import com.fasterxml.jackson.annotation.JsonAutoDetect;
import com.fasterxml.jackson.annotation.PropertyAccessor;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.SerializationFeature;
import com.github.benmanes.caffeine.cache.Cache;
import org.springframework.cache.CacheManager;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.util.Collection;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.ConcurrentMap;

@RestController
@RequestMapping("cache")
public class CacheController {
    private final CacheManager cacheManager;
    private final ObjectMapper objectMapper;

    public CacheController(final CacheManager cacheManager) {
        this.cacheManager = cacheManager;
        this.objectMapper = new ObjectMapper();
        this.objectMapper.setVisibility(PropertyAccessor.FIELD, JsonAutoDetect.Visibility.ANY);
        this.objectMapper.configure(SerializationFeature.FAIL_ON_EMPTY_BEANS, false);
    }

    @GetMapping("/names")
    public Collection<String> getCacheNames() {
        return cacheManager.getCacheNames();
    }

    @GetMapping("{cacheName}")
    public Map<String, Object> getEntriesForCache(@PathVariable(name = "cacheName") final String cacheName) throws JsonProcessingException {
        final Cache<String, Object> cache = (Cache<String, Object>) cacheManager.getCache(cacheName).getNativeCache();

        final ConcurrentMap<String, Object> data = cache.asMap();
        final String json = objectMapper.writeValueAsString(data);

        final TypeReference<HashMap<String,Object>> typeRef = new TypeReference<>() {};
        return objectMapper.readValue(json, typeRef);
    }

    @GetMapping("entries")
    public Map<String, Map<String, Object>> getAllEntries() throws JsonProcessingException {
        final Map<String, Map<String, Object>> entries = new HashMap<>();
        for(final String cacheName: getCacheNames()){
            entries.put(cacheName, getEntriesForCache(cacheName));
        }
        return entries;
    }
}
 

Ответ №5:

 var cache = cacheManager.getCache("CACHE_NAME");
var nativeCache = (ConcurrentHashMap<?, ?>) cache.getNativeCache();

for (var entry: nativeCache.entrySet()){
    // Access entry key and value
    entry.getKey()
    entry.getValue()
}