利用spring的拦截器自定义缓存的实现实例代码

网友投稿 264 2023-02-20


利用spring的拦截器自定义缓存的实现实例代码

本文研究的主要是利用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,HhpJbsItkb 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的拦截器自定义缓存的实现实例代码的全部内容,希望对大家有所帮助。感兴趣的朋友可以继续参阅本站其他相关专题,如有不足之处,欢迎留言指出。感谢朋友们对本站的支持!


版权声明:本文内容由网络用户投稿,版权归原作者所有,本站不拥有其著作权,亦不承担相应法律责任。如果您发现本站中有涉嫌抄袭或描述失实的内容,请联系我们jiasou666@gmail.com 处理,核实后本网站将在24小时内删除侵权内容。

上一篇:Vue组件化开发思考
下一篇:Java poi导出Excel下载到客户端
相关文章

 发表评论

暂时没有评论,来抢沙发吧~