用SPRING AOP实现主动缓存
缓存的实现最简单的模式,我称作为get set invalid 法,这也是缓存中最常用的一种模式,以前实现缓存(特别是后加)一般都会写一大堆诸如:
?
?
这样在指定包的地方都会被拦截,方法被拦截了干什么还是一个问题,这里我使用了注入,一共有两类注入,一种叫CheckCache一种叫FlushCache.Flush是用来delete缓存的 checkcache是用来检查缓存的,典型的get时候用check而update时候用flush.由于缓存key是来自于参数的,所以这个注解我定义了三个参数:
?
?
?
/** * 通过参数得到前缀 * * @param flushCache * @param args * @return */public List<Object> getFlushKey(FlushCache flushCache, Object[] args) {List<Object> ret = new ArrayList<Object>();if (flushCache != null) {for (int i = 0; i < flushCache.cachePrefix().length; i++) {String prefix = flushCache.cachePrefix()[i];List<String> paramList = this.genParamList(flushCache, i, args,prefix);List<String> rangeList = this.genRange(flushCache, i);for (String paramItem : paramList) {if (rangeList.size() > 0) {for (String rangeItem : rangeList) {StringBuilder sb = new StringBuilder();sb.append(paramItem);sb.append(rangeItem);ret.add(sb.toString());}} else {// StringBuilder sb = new StringBuilder();// sb.append(paramItem);ret.add(paramItem);}}}this.removeDuplicated(ret);}return ret;}private List<String> genParamList(FlushCache flushCache, int index,Object[] args, String prefix) {List<String> ret = new ArrayList<String>();List<String> paramList;if (index <= (flushCache.paramList().length - 1)) {// 对应的关系paramList = this.getPrefix(flushCache.paramList()[index]);} else {paramList = this.getPrefix(flushCache.paramList()[0]);}for (String argStr : paramList) {List<Object> argsValue = valueProcessManager.getValue(argStr, args);if (ret.size() > 0) {List<String> tempRet = new ArrayList<String>();for (String tempItem : ret) {for (Object tempObj : argsValue) {StringBuilder sbTemp = new StringBuilder();sbTemp.append(tempItem);sbTemp.append(KEY_SPILIT);sbTemp.append(tempObj);tempRet.add(sbTemp.toString());}}ret.clear();ret.addAll(tempRet);} else {for (Object item : argsValue) {ret.add(prefix + KEY_SPILIT + item.toString());}}}if (ret.size() == 0) {ret.add(prefix + KEY_SPILIT);}return ret;}private List<String> genRange(FlushCache flushCache, int index) {List<String> ret = new ArrayList<String>();if (null != flushCache.range()) {String range;if (index <= (flushCache.range().length - 1)) {// 对应的关系range = flushCache.range()[index];} else {range = flushCache.range()[0];}Map<String, Integer> map = JsonUtils.mapFromJson(range,Integer.class);KeyRanger keyRanger = KeyRanger.getInstance(map);if (keyRanger.getIsRange() > 0) {for (int j = keyRanger.getRangeStart(); j <= keyRanger.getRangeEnd(); j = j + keyRanger.getRangeStep()) {StringBuilder sb = new StringBuilder();sb.append(KEY_SPILIT);sb.append(j);ret.add(sb.toString());}}}return ret;}// 去除重复KEYprivate void removeDuplicated(List<Object> input) {List<Object> tempList = new ArrayList<Object>(input);HashSet<Object> tempSet = new HashSet<Object>(tempList);input.clear();for (Object obj : tempSet) {input.add(obj);}}public String getCheckKey(CacheCheck cacheCheck, Object[] args) {StringBuffer ret = new StringBuffer();ret.append(cacheCheck.cachePrefix());for (String argStr : cacheCheck.paramList()) {List<Object> argsValue = valueProcessManager.getValue(argStr, args);if (argsValue != null) {for (Object oChild : argsValue) {if (oChild != null) {ret.append(KEY_SPILIT);ret.append(oChild);}}}}logger.info(ret.toString());return ret.toString();}private List<String> getPrefix(String keys) {List<String> ret = new ArrayList<String>();if (null != keys) {String[] arr = keys.split(",");if (null != arr) {for (String s : arr) {if (!TBStringUtil.isBlank(s)) {ret.add(s);}}}}return ret;}?
变成贴代码了....天太热不想多打字,呵呵,大家凑合看,基本上看下spring配置就知道大概的意图了,试用下来对于一般的前后台应用足够了,但是要注意,拦截的方法一定是要业务层的,另外前后台的get方法最好分开,否则缓存一旦配置有问题,就会导致后台更新不了的故障,这个要注意...
over,其实只是想提供一种思路至于实现就贻笑大方了...