OSCache缓存监控实现

最近一个项目用到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或持久化也能实现监控。

 

你可能感兴趣的:(OSCache缓存监控实现)