java 如何使用 spring 缓存抽象返回条目数

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/14035799/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-31 14:49:56  来源:igfitidea点击:

How to return number of entries using spring cache abstraction

javaspringcaching

提问by Solubris

I am using spring cache abstraction to cache objects in the service layer. This is fine for simple get/put operations, as follows:

我正在使用 spring 缓存抽象来缓存服务层中的对象。这适用于简单的 get/put 操作,如下所示:

static private final String cacheName = "messages";

@CacheEvict(value=cacheName, key="#message.id")
public void deleteMessage(Message message) {
...
}

@Cacheable(value=cacheName, key="#id")
public Message findMessage(Long id) {
...
}

@CachePut(value=cacheName, key="#message.id")
public void saveMessage(Message message) {
...
}

@CachePut(value=cacheName, key="#message.id")
public Message updateMessage(Message message) {
...
}

However, what annotation would I use for the following method:

但是,对于以下方法,我将使用什么注释:

public long countAllMessages() {
...
}

Since all the objects will be in the cache, there should be a way to get the answer from the cache and not having to go to the repository layer.

由于所有对象都将在缓存中,因此应该有一种方法可以从缓存中获取答案,而不必转到存储库层。

Also, the cache is being applied on the following method:

此外,缓存正在应用于以下方法:

@Cacheable(cacheName)
public List<Message> findAllMessages() {
...
}

I could make the count method call the find all method like this:

我可以让 count 方法像这样调用 find all 方法:

public long countAllMessages() {
    return findAllMessages().size();
}

But this would not be efficient in the case where the cache is disabled, as the call would then load all records from the db instead of doing a SELECT COUNT(*)...

但这在缓存被禁用的情况下效率不高,因为调用将从数据库加载所有记录而不是执行 SELECT COUNT(*) ...

回答by Jason Day

The Spring cache abstraction doesn't currently provide a direct way of accessing statistics about the underlying caches. For example, there is no direct way to get the size of all the caches, the keys of the cached objects, etc. It's a higher level abstraction than that. You can, however, get access to the underlying native cache classes via the Cache#getNativeCache()method. Grabbing an instance of Cache from the CacheManager class will give you access to this method. Assuming you know the underlying types of the Cache instances managed by the CacheManager, you can cast them to the appropriate types and gain access to the helper methods on each (assuming there are any).

Spring 缓存抽象目前不提供访问有关底层缓存的统计信息的直接方法。例如,没有直接的方法可以获取所有缓存的大小、缓存对象的键等。这是一个更高级别的抽象。但是,您可以通过Cache#getNativeCache()方法访问底层本机缓存类。从 CacheManager 类中获取 Cache 的实例将使您能够访问此方法。假设您知道 CacheManager 管理的 Cache 实例的底层类型,您可以将它们强制转换为适当的类型并获得对每个类型的辅助方法的访问(假设有任何)。

For example, if your underlying cache store is EHCache, you can grab an instance of the Cache named "messages" by calling CacheManager#getCache("messages"). You'd then be able to check the type and cast the type to net.sf.ehcache.Ehcache, from which you can call the various statistics helper methods (eg. getStatistics()).

例如,如果您的底层缓存存储是 EHCache,您可以通过调用CacheManager#getCache("messages")获取名为“messages”的缓存实例。然后您就可以检查类型并将类型转换为net.sf.ehcache.Ehcache,您可以从中调用各种统计辅助方法(例如getStatistics())。

Here's an example of going through all the caches managed by CacheManager, checking if they're of type net.sf.ehcache.Ehcache, and subsequently getting their statistics.

下面是一个示例,它遍历 CacheManager 管理的所有缓存,检查它们是否属于 net.sf.ehcache.Ehcache 类型,然后获取它们的统计信息。

public class EhCacheStatistics {
  private CacheManager cacheManager;

  @Inject
  public void setCacheManager(CacheManager cacheManager) {
    this.cacheManager = cacheManager;
  }

  public long getTotalEhCacheSize() {
    long totalSize = 0l;
    for (String cacheName : cacheManager.getCacheNames()) {
      Cache cache = cacheManager.getCache(cacheName);
      Object nativeCache = cache.getNativeCache();
      if (nativeCache instanceof net.sf.ehcache.Ehcache) {
        net.sf.ehcache.Ehcache ehCache = (net.sf.ehcache.Ehcache) nativeCache;
        totalSize += ehCache.getStatistics().getObjectCount();
      }
    }
    return totalSize;
  }
}