转载请注明出处: http://renjie120.iteye.com/
在项目中经常需要使用缓存下拉菜单的值,可以使用一个map进行缓存管理;单例模式在项目中经常要使用,是很有用的一个设计模式;ThreadLocal在自己的一个框架中使用了,其本身也是被spring框架所使用来管理例如事务等,很有用的一个java类!
1.提供一个改造的简单的缓存管理类CacheManager
2.单例模式的简单实现
3.ThreadLocal的使用举例
1.CacheManager类,从名字看是管理Cache的管理器,主要有两个类:
package com.lsframe.cache; public class Cache { private String key;// 缓存ID private Object value;// 缓存数据 private long timeOut;// 更新时间 private boolean expired; // 是否终止 public Cache() { super(); } public Cache(String key, Object value, long timeOut, boolean expired) { this.key = key; this.value = value; this.timeOut = timeOut; this.expired = expired; } public String getKey() { return key; } public long getTimeOut() { return timeOut; } public Object getValue() { return value; } public void setKey(String string) { key = string; } public void setTimeOut(long l) { timeOut = l; } public void setValue(Object object) { value = object; } public boolean isExpired() { return expired; } public void setExpired(boolean b) { expired = b; } }
package com.lsframe.cache; import java.util.ArrayList; import java.util.HashMap; import java.util.Iterator; public class CacheManager { private static HashMap cacheMap = new HashMap(); // 单实例构造方法 private CacheManager() { super(); } // 获取布尔值的缓存 public static boolean getSimpleFlag(String key) { try { return (Boolean) cacheMap.get(key); } catch (NullPointerException e) { return false; } } public static long getServerStartdt(String key) { try { return (Long) cacheMap.get(key); } catch (Exception ex) { return 0; } } // 设置布尔值的缓存 public synchronized static boolean setSimpleFlag(String key, boolean flag) { if (flag && getSimpleFlag(key)) {// 假如为真不允许被覆盖 return false; } else { cacheMap.put(key, flag); return true; } } public synchronized static boolean setSimpleFlag(String key, long serverbegrundt) { if (cacheMap.get(key) == null) { cacheMap.put(key, serverbegrundt); return true; } else { return false; } } // 得到缓存。同步静态方法 private synchronized static Cache getCache(String key) { return (Cache) cacheMap.get(key); } // 判断是否存在一个缓存 private synchronized static boolean hasCache(String key) { return cacheMap.containsKey(key); } // 清除所有缓存 public synchronized static void clearAll() { cacheMap.clear(); } // 清除某一类特定缓存,通过遍历HASHMAP下的所有对象,来判断它的KEY与传入的TYPE是否匹配 public synchronized static void clearAll(String type) { Iterator i = cacheMap.entrySet().iterator(); String key; ArrayListarr = new ArrayList(); try { while (i.hasNext()) { java.util.Map.Entry entry = (java.util.Map.Entry) i.next(); key = (String) entry.getKey(); if (key.startsWith(type)) { // 如果匹配则删除掉 arr.add(key); } } for (int k = 0; k < arr.size(); k++) { clearOnly(arr.get(k)); } } catch (Exception ex) { ex.printStackTrace(); } } // 清除指定的缓存 public synchronized static void clearOnly(String key) { cacheMap.remove(key); } // 载入缓存 public synchronized static void putCache(String key, Cache obj) { cacheMap.put(key, obj); } /** * 获取缓存信息. * @param key * @return */ public static Cache getCacheInfo(String key) { if (hasCache(key)) { Cache cache = getCache(key); if (cacheExpired(cache)) { // 调用判断是否终止方法 cache.setExpired(true); } return cache; } else return null; } /** * 载入缓存信息. * @param key * @param obj * @param dt * @param expired */ public static void putCacheInfo(String key, Cache obj, long dt, boolean expired) { Cache cache = new Cache(); cache.setKey(key); cache.setTimeOut(dt + System.currentTimeMillis()); // 设置多久后更新缓存 cache.setValue(obj); cache.setExpired(expired); // 缓存默认载入时,终止状态为FALSE cacheMap.put(key, cache); } /** * 重写载入缓存信息方法. * @param key * @param obj * @param dt */ public static void putCacheInfo(String key, Cache obj, long dt) { Cache cache = new Cache(); cache.setKey(key); cache.setTimeOut(dt + System.currentTimeMillis()); cache.setValue(obj); cache.setExpired(false); cacheMap.put(key, cache); } /** * 判断缓存是否终止. * @param cache * @return */ public static boolean cacheExpired(Cache cache) { if (null == cache) { // 传入的缓存不存在 return false; } long nowDt = System.currentTimeMillis(); // 系统当前的毫秒数 long cacheDt = cache.getTimeOut(); // 缓存内的过期毫秒数 if (cacheDt <= 0 || cacheDt > nowDt) { // 过期时间小于等于零时,或者过期时间大于当前时间时,则为FALSE return false; } else { // 大于过期时间 即过期 return true; } } /** * 获取缓存中的大小. * @return */ public static int getCacheSize() { return cacheMap.size(); } /** * 获取指定的类型的大小 * @param type * @return */ public static int getCacheSize(String type) { int k = 0; Iterator i = cacheMap.entrySet().iterator(); String key; try { while (i.hasNext()) { java.util.Map.Entry entry = (java.util.Map.Entry) i.next(); key = (String) entry.getKey(); if (key.indexOf(type) != -1) { // 如果匹配则删除掉 k++; } } } catch (Exception ex) { ex.printStackTrace(); } return k; } /** * 获取缓存对象中的所有键值名称. * @return */ public static ArrayList getCacheAllkey() { ArrayList a = new ArrayList(); try { Iterator i = cacheMap.entrySet().iterator(); while (i.hasNext()) { java.util.Map.Entry entry = (java.util.Map.Entry) i.next(); a.add((String) entry.getKey()); } } catch (Exception ex) { } finally { return a; } } /** * 获取缓存对象中指定类型的键值名称. * @param type * @return */ public static ArrayList getCacheListkey(String type) { ArrayList a = new ArrayList(); String key; try { Iterator i = cacheMap.entrySet().iterator(); while (i.hasNext()) { java.util.Map.Entry entry = (java.util.Map.Entry) i.next(); key = (String) entry.getKey(); if (key.indexOf(type) != -1) { a.add(key); } } } catch (Exception ex) { } finally { return a; } } }
使用举例:
public List getAllTallyTypes(){ List allTallyTypes = null; TallyTypeDao tallyTypeDao = new TallyTypeDao(); //从缓存中取列表,对于这里类似是取字典表的数据,所以可以使用缓存。 if(CacheManager.getCacheInfo("tallyTypes")==null){ allTallyTypes = tallyTypeDao.doGetAllTallyTypes( "from tallyBook.pojo.TallyType"); Cache c = new Cache(); c.setKey("tallyTypes"); c.setValue(allTallyTypes); CacheManager.putCache("tallyTypes",c); }else{ allTallyTypes = (List)CacheManager.getCacheInfo("tallyTypes").getValue(); } return allTallyTypes; }
2.关于单例类的举例,截取代码自改造的一个简单的数据库连接池代码:
public class DBPoolManager { /** * 返回连接池管理对象的实例 * @return */ public static DBPoolManager getInstance() { if(dbManager==null){ dbManager = new DBPoolManager(); } //创建了一次就计数累加一次。 clientCount++; return dbManager; } private DBPoolManager() { //构造函数中进行初始化操作 init(); } private void init() { try { pros = new Properties(); pros.load(this.getClass().getResourceAsStream("/db.properties")); } catch (Exception ex) { log.error("没有找到连接池配置文件", ex); } loadDriver(); createPool(); } }
单例模式的典型特征之一,就是私有的构造函数!然后有一个init()这样的方法返回对象的实例.
3.使用本地线程变量的实例,代码来自改造的一个MVC框架片段,用于设置了request变量之后,再方便取出request变量:
package com.lsframe.mvc; import java.util.Map; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; public class ActionContext { private static ThreadLocalactionContext = new ThreadLocal (); /** * 取得上下文的内容. * @return */ public static ActionContext getContext() { return (ActionContext) actionContext.get(); } /** * 设置上下文. * @param context */ public static void setContext(ActionContext context) { actionContext.set(context); } private Map context = null; /** * 初始化上下文环境. * @param context */ public ActionContext(Map context) { this.context = context; } /** * 得到上下文. * @return */ public Map getContextMap() { return context; } /** * 取得上下文中的值. * @param key * @return */ public Object get(String key) { return context.get(key); } /** * 取得上下文中的HttpServletRequest对象. * @return */ public HttpServletRequest getHttpServletRequest() { return (HttpServletRequest) context.get("HttpServletRequest"); } /** * 取得上下文中的HttpServletResponse. * @return */ public HttpServletResponse getHttpServletResponse() { return (HttpServletResponse) context.get("HttpServletResponse"); } }
设置request的时候,只需要使用:
Map context = new HashMap(); context.put("HttpServletRequest", request); context.put("HttpServletResponse", response); ActionContext actionContext = new ActionContext(context); ActionContext.setContext(actionContext);
如此简单!!多谢这个方便的本地线程变量,然后就可以在一个请求的任意位置得到request了...是不是和session很相似的机制,好像session就是用这个实现的...