package test.cache;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;
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.boot.autoconfigure.session.SessionProperties;
import org.springframework.core.DefaultParameterNameDiscoverer;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Component;
import redis.RedisUtils;
import redis.clients.jedis.Jedis;
import java.lang.annotation.Annotation;
import java.lang.reflect.Method;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.locks.Lock;
@Aspect
@Component
public class TestCacheAop {
ConcurrentHashMap<String,String> lock = new ConcurrentHashMap();
@Autowired
RedisTemplate redisTemplate;
@Pointcut(value="execution(public * test*.*.*.*(..))&&@annotation(TestCache)")
public void cachePointcut() {
}
@Around("cachePointcut()")
public Object around (ProceedingJoinPoint joinPoint) throws NoSuchMethodException {
//Annotation annotation = joinPoint.getTarget().getClass().getAnnotation(TestCache.class);
TestCache testCache = ((MethodSignature)joinPoint.getSignature()).getMethod().getAnnotation(TestCache.class);
if(testCache == null) {
return null;
}
String key = testCache.value();
if(key==null) {
return null;
}
MethodSignature methodSignature =(MethodSignature) joinPoint.getSignature();
Method method = joinPoint.getTarget().getClass().getMethod(methodSignature.getName(),methodSignature.getMethod().getParameterTypes());
//java编译后的方法参数默认是不会显示参数名称的需要转换
DefaultParameterNameDiscoverer discoverer = new DefaultParameterNameDiscoverer();
String[] parameters = discoverer.getParameterNames(method);
String cacheKey = key;
for(int i=0;i<parameters.length;i++) {
if(parameters[i].equals(key)) {
cacheKey = String.valueOf(joinPoint.getArgs()[i]);
break;
}
}
Object value = redisTemplate.opsForValue().get(cacheKey);
if(value!=null) {
return value;
}
//防止缓存雪崩
String cacheFlag = lock.putIfAbsent(cacheKey,"true");
Object obj = null;
if(cacheFlag == null) {
try {
obj = joinPoint.proceed();
redisTemplate.opsForValue().set(cacheKey,obj);
} catch(Throwable throwable) {
throwable.printStackTrace();
}
return obj;
}else {
return "当前系统忙";
}
}
}