/**
* 元注解 用来标识查询数据库的方法
*/
@Documented
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface UseRedisCache {
/**
* 缓存超时时间控制,> 0 则做超时控制
* @return
*/
int expireSeconds() default -1;
}
import java.lang.reflect.Method;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import cn.com.amway.app.client.RedisClient;
import cn.com.amway.app.configuration.ConfTable;
import cn.com.amway.framework.annotation.UseRedisCache;
/**
* AOP实现Redis缓存处理
*
* @decr
* @author jlchent
* @date 2018年7月18日
*
*/
@Component
@Aspect
public class RedisAspect {
private static final Logger logger = LoggerFactory.getLogger(RedisAspect.class);
@Autowired
private RedisClient redisCache;
/**
* 拦截所有元注解RedisCache注解的方法
*/
@Pointcut("@annotation(cn.com.framework.annotation.UseRedisCache)")
public void pointcutMethod() {
}
/**
* 环绕处理,先从Redis里获取缓存,查询不到,就通过method查询, 然后再保存到Redis缓存里
*
* @param joinPoint
* @return
* @throws Throwable
*/
@Around("pointcutMethod()")
public Object around(ProceedingJoinPoint joinPoint) throws Throwable {
// 前置:从Redis里获取缓存
// 先获取目标方法参数
long startTime = System.currentTimeMillis();
Object[] args = joinPoint.getArgs();
String pragrm = "";
if (args != null && args.length > 0) {
for (int i = 0; i < args.length; i++) {
pragrm = "_"+pragrm + String.valueOf(args[i]) ;
}
}
// 获取目标方法所在类
String target = joinPoint.getTarget().toString();
String className = target.split("@")[0];
// 获取目标方法的方法名称
String methodName = joinPoint.getSignature().getName();
int expireSeconds = 0;
Class<?> returnType = Object.class;
try {
Class<?> clz = Class.forName(className);
Class<?>[] classes = null;
if (args != null && args.length > 0) {
classes = new Class[args.length];
for (int i = 0; i < classes.length; i++) {
classes[i] = args[i].getClass();
}
}
Method method = clz.getMethod(methodName, classes);
returnType = method.getReturnType();
UseRedisCache useRedisCache = method.getAnnotation(UseRedisCache.class);
if (useRedisCache != null && useRedisCache.expireSeconds() > 0) {
expireSeconds = useRedisCache.expireSeconds();
}
} catch (ClassNotFoundException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
logger.warn("类包"+className+"不存在", e1);
throw e1;
}
// redis中key格式: applId:方法名称
String redisKey = ConfTable.REDIS_ASPECT_PREFIX + className + "." + methodName + pragrm;
Object obj = (Object)redisCache.getObjFromRedis(redisKey, returnType);
if (obj != null) {
logger.info("**********从Redis中查到了数据**********");
logger.info("Redis的KEY值:" + redisKey);
logger.info("REDIS的VALUE值类型:" + obj.getClass().getName());
return obj;
}
long endTime = System.currentTimeMillis();
logger.info("Redis缓存AOP处理所用时间(毫秒):" + (endTime - startTime));
logger.info("**********没有从Redis查到数据**********");
logger.info("**********开始通过Method查询数据**********");
obj = joinPoint.proceed();
if (obj == null) {
logger.info("**********获取到null数据**********");
return null;
}
// 后置:将数据库查到的数据保存到Redis
String code = "";
if (expireSeconds > 0) {
code = redisCache.saveObjToRedis(redisKey, obj, expireSeconds);
} else {
code = redisCache.saveObjToRedis(redisKey, obj);
}
if (("OK").equals(code)) {
logger.info("**********数据成功保存到Redis缓存!!!**********");
logger.info("Redis的KEY值:" + redisKey);
logger.info("REDIS的VALUE值类型:" + obj.getClass().getName());
}
return obj;
}
}