如何在Ehcache 3中获取所有缓存名称及数据量并封装到List中
Hey there! Let's work through this together since you're new to Ehcache 3. First, let's fix a small issue in your existing code before jumping to the solution:
Your line
System.getProperties().setProperty("java -Dnet.sf.ehcache.use.classic.lru", "true");isn't doing what you think it does. Thejava -Dprefix is for JVM startup arguments—when setting properties via code, you just need the property name. Also, that property is for Ehcache 2; Ehcache 3 uses different configuration for eviction policies (LRU is actually the default for heap caches anyway). So you can safely remove that line, or we can add explicit eviction config to your cache setup if you need it later.
Now, onto your main goal: creating a standalone function to return all cache names and their entry counts for UI status display. Ehcache 3's CacheManager has built-in methods to make this straightforward.
Step-by-Step Solution
- Use
CacheManager.getCacheNames()to retrieve all registered cache names. - For each cache name, fetch the cache instance with
CacheManager.getCache(). - Call
Cache.getSize()to get the number of entries in that cache.
Here's how you can implement this in your ListPlanImpl class:
import java.util.HashMap; import java.util.Map; import org.ehcache.Cache; import org.ehcache.CacheManager; // ... rest of your class code ... /** * Returns a map of all cache names to their respective entry counts * @return Map<String, Long> where key = cache name, value = number of entries */ public Map<String, Long> getCacheStatus() { Map<String, Long> cacheStatusMap = new HashMap<>(); // Get all cache names from the CacheManager for (String cacheName : cacheManager.getCacheNames()) { // Fetch the cache instance (safe cast since you know the types) Cache<String, GenericClassForList> cache = cacheManager.getCache(cacheName, String.class, GenericClassForList.class); if (cache != null) { // Get the number of entries in the cache long entryCount = cache.getSize(); cacheStatusMap.put(cacheName, entryCount); } } return cacheStatusMap; }
How to Use This Function
In your UI-facing code or service layer, you can call this method like so:
// If using CDI, inject the ListPlanImpl instance instead of new-ing it ListPlanImpl listPlanService = new ListPlanImpl(); Map<String, Long> cacheStatus = listPlanService.getCacheStatus(); // Iterate over the map to display in UI for (Map.Entry<String, Long> entry : cacheStatus.entrySet()) { System.out.println("Cache: " + entry.getKey() + " | Entry Count: " + entry.getValue()); }
Key Notes
- Null Safety: We check if
cacheis null because a cache might have been destroyed after being created. - Performance:
getSize()is an O(1) operation for most Ehcache configurations (like heap-only caches), so it's efficient for UI display. - Thread Safety: Since your class is
@Stateless, you might want to makecacheManagera static variable or use CDI injection for better instance management in an EJB environment.
Bonus: Fixing Cache Creation Best Practice
In your putInCache() method, you're creating caches every time the method is called—this will throw an exception if the cache already exists. Add a check first:
// Check if operating parameters cache exists before creating if (cacheManager.getCache("cacheOfOperatingParameters") == null) { this.operatingParametersCache = cacheManager.createCache("cacheOfOperatingParameters", CacheConfigurationBuilder.newCacheConfigurationBuilder( String.class, GenericClassForList.class, ResourcePoolsBuilder.heap(1000000000)) .withExpiry(Expirations.timeToLiveExpiration(Duration.of(60000, TimeUnit.SECONDS)))); } // Then put the data operatingParametersCache.put(CACHE_OPERATING_PARAMETER, new GenericClassForList(this.operatingParamService.getOperatingParamDTO()));
This prevents duplicate cache creation errors.
内容的提问来源于stack exchange,提问作者Ashwin Karki

