OSCache缓存监控实现

来源:互联网 发布:淘宝网红店排行榜 编辑:程序博客网 时间:2024/05/16 14:20

最近一个项目用到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;  


所以只能用反射机制暴力破解了(按照Sun公司的JVM规范是许可的^_^),主要代码如下:


1) OsCacheUtil.java

 

    /**           * 通过反射机制获取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;           }  


2)  oscache_list.jsp

 

    <%@ 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>  


小结:


本例子只实现ServletCache中的Application Scop的cache list功能;通过Listener或持久化也能实现监控。