我们经常遇到一种场景, 就是查询数据, 首先去Redis中获取, 如果有数据就返回,
如果没有就去数据库中进行查询,然后将它放入到数据当中,这样的代码与业务没有太大关系, 可以抽离出来,
您可能会说Spring的@Cache注解可以实现啊, 但是它的实现不灵活, 有时候还是要自己定义一些东西的.
import com.alibaba.fastjson.JSON;
import com.zhangmen.aioneservice.core.utils.RedisUtil;
import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.AfterReturning;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import java.lang.reflect.Method;
import java.util.Random;
/**
* 获取数据代理类
*
* @author: baifan
* @date: 2021/2/1
*/
@Slf4j
@Component
@Aspect
public class DBGetProxy {
@Autowired
RedisUtil redisUtil;
@Pointcut("@annotation(com.zhangmen.aioneservice.core.aop.DBToRedisAop)")
public void pointCut() {
}
@Around("pointCut()")
public Object beforeGetDataFromDB(ProceedingJoinPoint joinPoint) throws Throwable {
// 获取方法名
String methodName = joinPoint.getSignature().getName();
// 反射获取目标类
Class<?> targetClass = joinPoint.getTarget().getClass();
// 拿到方法对应的参数类型
Class<?>[] parameterTypes = ((MethodSignature) joinPoint.getSignature()).getParameterTypes();
// 根据类、方法、参数类型(重载)获取到方法的具体信息
Method objMethod = targetClass.getMethod(methodName, parameterTypes);
// 拿到方法定义的注解信息
DBToRedisAop dbToRedisAop = objMethod.getDeclaredAnnotation(DBToRedisAop.class);
String content = dbToRedisAop.content();
String rawKey = dbToRedisAop.rawKey();
Object[] args = joinPoint.getArgs();
String key = genKey(rawKey, args);
log.info("获取{}开始...,key为 {}", content, key);
Object result = redisUtil.get(key);
if (result != null) {
log.info("从缓存中获取到{}:{}", content, result.toString());
// 得到被代理方法的返回值类型
//Class returnType = ((MethodSignature) joinPoint.getSignature()).getReturnType();
} else {
result = joinPoint.proceed(args);
redisUtil.set(key, result, randomTime(3600));
}
return result;
}
private long randomTime(long time) {
Random random = new Random();
return Long.valueOf(random.nextInt(30)) + time;
}
private String genKey(String rawKey, Object[] args) {
for (Object arg : args) {
if (rawKey.contains("{}")) {
rawKey = rawKey.replaceFirst("\\{\\}", String.valueOf(arg));
}
}
return rawKey;
}
}
``
网友评论