您好,登錄后才能下訂單哦!
小編給大家分享一下如何利用spring攔截器實現自定義緩存,相信大部分人都還不怎么了解,因此分享這篇文章給大家參考一下,希望大家閱讀完這篇文章后大有收獲,下面讓我們一起去了解一下吧!
本文研究的主要是利用spring的攔截器自定義緩存的實現,具體實現代碼如下所示。
Memcached 是一個高性能的分布式內存對象緩存系統,用于動態Web應用以減輕數據庫負載。它通過在內存中緩存數據和對象來減少讀取數據庫的次數,從而提高動態、數據庫驅動網站的速度。本文利用Memcached 的實例和spring的攔截器實現緩存自定義的實現。利用攔截器讀取自定義的緩存標簽,key值的生成策略。
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; }
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 ""; }
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(); }
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; }
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(); }
//使用攔截到方法的參數生成參數 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(); }
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 private String getKeyWithGenerator(MethodInvocation invoction, String keyGenerator) throws Exception { Class<?> ckg = Class.forName(keyGenerator); CacheKeyGenerator ikg = (CacheKeyGenerator)ckg.newInstance(); return ikg.generate(invoction.getArguments()); }
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攔截器實現自定義緩存”這篇文章的所有內容,感謝各位的閱讀!相信大家都有了一定的了解,希望分享的內容對大家有所幫助,如果還想學習更多知識,歡迎關注億速云行業資訊頻道!
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。