公告:欢迎访问,查看更多资源请点我^.^!            点我关闭广告
AOP实现Memcached注解缓存
2017-07-14 14:35:42
2947人阅读
评论(2)
分类:NoSql

为了方便使用memcached缓存,特编写了aop注解工具实现缓存

1. 项目结构

blob.png


2. 注解编写

import java.lang.annotation.*;

/**
* @author 赵超
*/
@Target({ElementType.PARAMETER, ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface Cached {
int value() default 60;//minute
}


3. CachedAop

import com.sys.job.util.StaticUtil;
import net.spy.memcached.MemcachedClient;
import org.apache.log4j.Logger;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.Signature;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.beans.factory.annotation.Autowired;

import java.lang.reflect.Method;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;

/**
* @author 赵超
* @Description memcached缓存aop
* @create 2017-06-26 8:40
**/
@Aspect
public class CacheAop {
private static Logger logger = Logger.getLogger(CacheAop.class);

@Autowired
private MemcachedClient memcachedClient;

@Pointcut("@annotation(com.sys.job.cache.aop.Cached)")
public void cachedAspect() {
}

@Around(value = "cachedAspect()")
public Object log(ProceedingJoinPoint pjp) throws Throwable {
int saveTime = 60;
// 获取方法名
Signature signature = pjp.getSignature();
String methodName = signature.getName();
String params = "(";
// 获取参数
Object[] args = pjp.getArgs();
for (Object object : args) {
params += object + "_";
}
params = params.contains("_") ? params.substring(0, params.length() - 1) : params;
String key = methodName + params + ")";

//获取方法的注解
Method targetMethod = ((MethodSignature)signature).getMethod();
Method realMethod = pjp.getTarget().getClass().getDeclaredMethod(methodName,
targetMethod.getParameterTypes());
if (realMethod.isAnnotationPresent(Cached.class)) {
Cached cached = realMethod.getAnnotation(Cached.class);
saveTime *= cached.value();
}
Object proceed;
if (StaticUtil.USE_MEMCACHED && memcachedClient.get(key) != null) {
try {
proceed = memcachedClient.get(key);
logger.info("CacheAop memcached: " + key);
} catch (Exception e) {
proceed = pjp.proceed(args);
memcachedClient.add(key, saveTime, proceed);
add(memcachedClient, methodName, saveTime, key);
logger.error("memcachedError", e);
}
} else {
proceed = pjp.proceed(args);
if (StaticUtil.USE_MEMCACHED && memcachedClient.get(key) == null) {
add(memcachedClient, methodName, saveTime, key);
memcachedClient.add(key, saveTime, proceed);
}
}
return proceed;
}

private static void add(MemcachedClient memcachedClient, String methodName,
int saveSeconds, String key) {
Map<String, Set<String>> save;
Set<String> set;
//判断memcached中是否存在key管理StaticUtil.memcachedKeys
if (memcachedClient.get(StaticUtil.memcachedKeys) != null) {
save = (Map<String, Set<String>>) memcachedClient.get(StaticUtil.memcachedKeys);
} else {
save = new HashMap<>();
}
if (save.containsKey(methodName) && save.get(methodName) != null) {
set = save.get(methodName);
} else {
set = new HashSet<>();
}
set.add(key);
logger.info("CacheAop Add save " + saveSeconds / 60 + "minutes memcached: " + key);
save.put(methodName, set);
if (memcachedClient.get(StaticUtil.memcachedKeys) != null) {
memcachedClient.replace(StaticUtil.memcachedKeys, 60 * 60 * 24, save);
} else {
memcachedClient.add(StaticUtil.memcachedKeys, 60 * 60 * 24, save);
}
logger.info("StaticUtil.memcachedKeys " + memcachedClient.get(StaticUtil.memcachedKeys));
}
}


4. MemcachedUtil中的有效方法

/**
* 删除memcached数据
* @param memcachedClient
* @param memcachedKey StaticUtil.memcachedKeys的key,作用类似于redis的field
* @return
*/
public static Integer delete(MemcachedClient memcachedClient, String memcachedKey) {
try {
if (memcachedClient.get(StaticUtil.memcachedKeys) != null) {
Map<String, Set<String>> save =
(Map<String, Set<String>>) memcachedClient.get(StaticUtil.memcachedKeys);
if (save.containsKey(memcachedKey) && save.get(memcachedKey) != null) {
Set<String> set = save.get(memcachedKey);
set.forEach(s -> memcachedClient.delete(s.toString()));
save.remove(memcachedKey);
memcachedClient.replace(StaticUtil.memcachedKeys, 60 * 60 * 24, save);
return 1;
}
}
return 0;
} catch (Exception e) {
e.printStackTrace();
}
return -1;
}


5. 使用

@Cached(30)
@Override
public Map getBlogList(String up, String scan, String time, String class_,
String info, Integer page, Integer limit) throws Exception {
Map<String, Object> back = new HashMap(5);
PageHelper.startPage(page, limit);
Page<Blog> res = blogDao.getBlogList(up, scan, time, class_, info);
back.put("resCode", res != null ? 1 : -1);
back.put("resData", res.getResult());
back.put("sumPage", res.getPages());
back.put("sumCount", res.getTotal());
return back;
}


6. 控制台

blob.png


分享一下:
赞一下(4)
博主资料
博主头像
zc521106
文章:34
浏览:19899
文章分类
Java(12)
NoSql(112)
数据库(12)
前端(12)
阅读排行
Java基础知识
(12)
NoSql应用
(112)
数据库Oracle语法
(12)
前端常用工具类
(12)
java web项目
(12)
linux安装mysql
(12)
评论区
这篇文章怎么样?写点评论吧!
姓名:
邮箱:
有回复时通知我:
发表
回复【10.20.30.32】:
此方法与springboot结合使用时,需要将MemcachedClient注入,无法注入则添加: @Bean public MemcachedClient memcachedClient() throws IOException { return new MemcachedClient(new InetSocketAddress(memUrl, memPort)); }
2018-06-01 15:31:44
也可以同样的思路使用AOP实现权限管理,详情请联系管理员或留言
2017-08-01 19:43:46
* 以上用户言论只代表其个人观点,不代表iBlog网站的观点或立场,如有任何疑问请随时联系管理员...