OSCache缓存监控实现
- - ITeye博客最近一个项目用到OsCache的页面片段缓存,google了一下居然没有找到OsCache的监控工具(list all keys from cache),于是大略读了一下OSCache-2.4.1的源码,发现Cache.java类的cacheMap定义成了私有变量,如下:. 所以只能用反射机制暴力破解了(按照Sun公司的JVM规范是许可的^_^),主要代码如下:.
最近一个项目用到OsCache的页面片段缓存,google了一下居然没有找到OsCache的监控工具(list all keys from cache),于是大略读了一下OSCache-2.4.1的源码,发现Cache.java类的cacheMap定义成了私有变量,如下:
/** * The actual cache map. This is where the cached objects are held. */ private AbstractConcurrentReadCache cacheMap = null;
/** * 通过反射机制获取Cache私有成员变量cacheMap, 2012/10/8, by jeffsang * @return */ public static AbstractConcurrentReadCache getCacheMap(ServletContext ctx) { //获取Cache对象实例 Cache cache = ServletCacheAdministrator.getInstance(ctx).getAppScopeCache(ctx); //通过反射机制获取Cache私有成员变量cacheMap AbstractConcurrentReadCache cacheMap = null; try { Field field = Cache.class.getDeclaredField("cacheMap" ); field.setAccessible( true); cacheMap = (AbstractConcurrentReadCache) field.get(cache); field.setAccessible( false); } catch (Exception e) { log.warn( "can't acquire oscache Cache.cacheMap! " , e); } return cacheMap; } /** * 获取ServletCache的全部Application Scope的cache, 2012/10/8, by jeffsang * @return */ public static Map getAppScopeCaches(ServletContext ctx) { Map map = new HashMap(); //获取Cache对象实例 Cache cache = ServletCacheAdministrator.getInstance(ctx).getAppScopeCache(ctx); //通过反射机制获取Cache私有成员变量cacheMap AbstractConcurrentReadCache cacheMap = getCacheMap(ctx); //返回包含在cacheMap中的Map关系的 Set视图。 @SuppressWarnings("unchecked") Set> setEntry = cacheMap.entrySet(); //使用Iterator遍历器 //Iterator> it = cacheMap.entrySet().iterator(); //使用for遍历cacheMap中的entrySet for (Map.Entry entry : setEntry) { String key = entry.getKey(); Object value = cache.getFromCache(key); //以下方法只能得到CacheEntry对象实例Id //Object value = entry.getValue(); map.put(key, value); } return map; }
<%@ page contentType="text/html; charset=UTF-8" %> <%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %> <%@ page import="java.util.*" %> <%@ page import="com.lasun.util.OsCacheUtil" %> <% Map<String, Object> map = OsCacheUtil.getAppScopeCaches(request.getServletContext()); request.setAttribute("map", map); %> <table border="1"> <tr> <th>No</th> <th>Key</th> <th>Value</th> </tr> <c:forEach var="entry" items="${map}" varStatus="status"> <tr> <td>${status.index+1}</td> <td>${entry.key}</td> <td>${entry.value}</td> </tr> </c:forEach> </table>