利用spring的拦截器自定义缓存的实现实例代码
程序员文章站
2023-08-13 21:12:47
本文研究的主要是利用spring的拦截器自定义缓存的实现,具体实现代码如下所示。
memcached 是一个高性能的分布式内存对象缓存系统,用于动态web应用以减轻数据库...
本文研究的主要是利用spring的拦截器自定义缓存的实现,具体实现代码如下所示。
memcached 是一个高性能的分布式内存对象缓存系统,用于动态web应用以减轻数据库负载。它通过在内存中缓存数据和对象来减少读取数据库的次数,从而提高动态、数据库驱动网站的速度。本文利用memcached 的实例和spring的拦截器实现缓存自定义的实现。利用拦截器读取自定义的缓存标签,key值的生成策略。
自定义的cacheable
package com.jeex.sci; @target(elementtype.method) @retention(retentionpolicy.runtime) @inherited @documented public @interface cacheable { string namespace(); string key() default ""; int[] keyargs() default { } ; string[] keyproperties() default { } ; string keygenerator() default ""; int expires() default 1800; }
自定义的cacheevict
package com.jeex.sci; @target(elementtype.method) @retention(retentionpolicy.runtime) @inherited @documented public @interface cacheevict { string namespace(); string key() default ""; int[] keyargs() default { } ; string[] keyproperties() default { } ; string keygenerator() default ""; }
spring如果需要前后通知的话,一般会实现methodinterceptor public object invoke(methodinvocation invocation) throws throwable
public object invoke(methodinvocation invoction) throws throwable { method method = invoction.getmethod(); cacheable c = method.getannotation(cacheable.class); if (c != null) { return handlecacheable(invoction, method, c); } cacheevict ce = method.getannotation(cacheevict.class); if (ce != null) { return handlecacheevict(invoction, ce); } return invoction.proceed(); }
处理cacheable标签
private object handlecacheable(methodinvocation invoction, method method, cacheable c) throws throwable { string key = getkey(invoction, keyinfo.fromcacheable(c)); if (key.equals("")) { if (log.isdebugenabled()){ log.warn("empty cache key, the method is " + method); } return invoction.proceed(); } long nstag = (long) memcachedget(c.namespace()); if (nstag == null) { nstag = long.valueof(system.currenttimemillis()); memcachedset(c.namespace(), 24*3600, long.valueof(nstag)); } key = makememcachedkey(c.namespace(), nstag, key); object o = null; o = memcachedget(key); if (o != null) { if (log.isdebugenabled()) { log.debug("cache hit: cache key = " + key); } } else { if (log.isdebugenabled()) { log.debug("cache miss: cache key = " + key); } o = invoction.proceed(); memcachedset(key, c.expires(), o); } return o; }
处理cacheevit标签
private object handlecacheevict(methodinvocation invoction, cacheevict ce) throws throwable { string key = getkey(invoction, keyinfo.fromcacheevict(ce)); if (key.equals("")) { if (log.isdebugenabled()) { log.debug("evicting " + ce.namespace()); } memcacheddelete(ce.namespace()); } else { long nstag = (long) memcachedget(ce.namespace()); if (nstag != null) { key = makememcachedkey(ce.namespace(), nstag, key); if (log.isdebugenabled()) { log.debug("evicting " + key); } memcacheddelete(key); } } return invoction.proceed(); }
根据参数生成key
//使用拦截到方法的参数生成参数 private string getkeywithargs(object[] args, int[] argindex) { stringbuilder key = new stringbuilder(); boolean first = true; for (int index: argindex) { if (index < 0 || index >= args.length) { throw new illegalargumentexception("index out of bound"); } if (!first) { key.append(':'); } else { first = false; } key = key.append(args[index]); } return key.tostring(); }
根据属性生成key
private string getkeywithproperties(object o, string props[]) throws exception { stringbuilder key = new stringbuilder(); boolean first = true; for (string prop: props) { //把bean的属性转为获取方法的名字 string methodname = "get" + prop.substring(0, 1).touppercase() + prop.substring(1); method m = o.getclass().getmethod(methodname); object r = m.invoke(o, (object[]) null); if (!first) { key.append(':'); } else { first = false; } key = key.append(r); } return key.tostring(); }
利用自定义的生成器生成key
//使用生成器生成key private string getkeywithgenerator(methodinvocation invoction, string keygenerator) throws exception { class<?> ckg = class.forname(keygenerator); cachekeygenerator ikg = (cachekeygenerator)ckg.newinstance(); return ikg.generate(invoction.getarguments()); }
保存key信息的帮助类
private static class keyinfo { string key; int[] keyargs; string keyproperties[]; string keygenerator; static keyinfo fromcacheable(cacheable c) { keyinfo ki = new keyinfo(); ki.key = c.key(); ki.keyargs = c.keyargs(); ki.keygenerator = c.keygenerator(); ki.keyproperties = c.keyproperties(); return ki; } static keyinfo fromcacheevict(cacheevict ce) { keyinfo ki = new keyinfo(); ki.key = ce.key(); ki.keyargs = ce.keyargs(); ki.keygenerator = ce.keygenerator(); ki.keyproperties = ce.keyproperties(); return ki; } string key() { return key; } int[] keyargs() { return keyargs; } string[] keyproperties() { return keyproperties; } string keygenerator() { return keygenerator; } }
参数的设置
//使用参数设置key @cacheable(namespace="blacklist", keyargs={0, 1}) public int anothermethond(int a, int b) { return 100; }
测试类:
package com.jeex.sci.test; import net.spy.memcached.memcachedclient; import org.junit.test; import org.springframework.context.applicationcontext; import org.springframework.context.support.filesystemxmlapplicationcontext; public class testmain { public static void main(string args[]) throws interruptedexception{ applicationcontext ctx = new filesystemxmlapplicationcontext("/src/test/resources/beans.xml"); memcachedclient mc = (memcachedclient) ctx.getbean("memcachedclient"); blacklistdaoimpl dao = (blacklistdaoimpl)ctx.getbean("blacklistdaoimpl"); while (true) { system.out.println("################################getting start######################"); mc.flush(); blacklistquery query = new blacklistquery(1, "222.231.23.13"); dao.searchblacklistcount(query); dao.searchblacklistcount2(query); blacklistquery query2 = new blacklistquery(1, "123.231.23.14"); dao.anothermethond(333, 444); dao.searchblacklistcount2(query2); dao.searchblacklistcount3(query2); dao.evict(query); dao.searchblacklistcount2(query); dao.evictall(); dao.searchblacklistcount3(query2); thread.sleep(300); } } }
总结
以上就是本文关于利用spring的拦截器自定义缓存的实现实例代码的全部内容,希望对大家有所帮助。感兴趣的朋友可以继续参阅本站其他相关专题,如有不足之处,欢迎留言指出。感谢朋友们对本站的支持!
上一篇: 你知道夏季海鲜吃什么好吗?
推荐阅读
-
Express + Node.js实现登录拦截器的实例代码
-
利用spring的拦截器自定义缓存的实现实例代码
-
利用canvas实现的加载动画效果实例代码
-
HTML5的自定义data-*实现图片切换或者轮播(代码实例)
-
jQuery 利用ztree实现树形表格的实例代码
-
php实现微信公众号创建自定义菜单功能的实例代码
-
利用jQuery实现简单的拖曳效果实例代码
-
vue自定义组件实现v-model双向绑定数据的实例代码
-
Android自定义View实现简单炫酷的球体进度球实例代码
-
FeignClient原理解析,100行代码实现feign功能,mybatis的mapper、dubbo、feign实现原理模拟。spring扫描自定义注解原理。Javassist实现动态代理原理