自定义注解
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
import java.util.concurrent.TimeUnit;
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface RedisCache {
String group();
String key() default "";
String condition() default "";
String unless() default "";
long time() default 30L;
TimeUnit unit() default TimeUnit.MINUTES;
}
AOP实现
import lombok.extern.java.Log;
import org.apache.commons.lang3.StringUtils;
import org.apache.ibatis.annotations.Param;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.expression.Expression;
import org.springframework.expression.spel.standard.SpelExpressionParser;
import org.springframework.expression.spel.support.StandardEvaluationContext;
import org.springframework.stereotype.Component;
import java.lang.annotation.Annotation;
import java.lang.reflect.Method;
@Aspect
@Component
@Log
public class RedisAop {
private SpelExpressionParser parserSpel = new SpelExpressionParser();
@Autowired
private RedisTemplate redisTemplate;
@Around(value = "@annotation(redisCache)")
public Object cache(ProceedingJoinPoint joinPoint, RedisCache redisCache) throws Throwable {
StringBuffer keyName = new StringBuffer(redisCache.group());
Boolean isCache = true;
if (!StringUtils.isEmpty(redisCache.key()) || !StringUtils.isEmpty(redisCache.condition())){
StandardEvaluationContext context = new StandardEvaluationContext();
MethodSignature methodSignature = (MethodSignature) joinPoint.getSignature();
Object[] args = joinPoint.getArgs();
String[] argNames = methodSignature.getParameterNames();
Method method = joinPoint.getTarget().getClass().getDeclaredMethod(methodSignature.getName(), methodSignature.getParameterTypes());
Annotation[][] annotations = method.getParameterAnnotations();
for (int i = 0; i < args.length; i++){
Annotation[] annotationArr = annotations[i];
String name = argNames[i];
for (Annotation annotation : annotationArr){
if (annotation instanceof Param) {
Param param = (Param) annotation;
name = param.value();
}
}
context.setVariable(name, args[i]);
}
if (!StringUtils.isEmpty(redisCache.key())){
Expression expression = this.parserSpel.parseExpression(redisCache.key());
String key = expression.getValue(context, String.class);
keyName.append(":").append(key);
}
if (!StringUtils.isEmpty(redisCache.condition())) {
Expression expression = this.parserSpel.parseExpression(redisCache.condition());
isCache = expression.getValue(context, Boolean.class);
}
}
Object obj = this.redisTemplate.opsForValue().get(keyName.toString());
if (obj != null) {
return obj;
}
obj = joinPoint.proceed();
if (!isCache) {
return obj;
}
if (!StringUtils.isEmpty(redisCache.unless())){
Expression expression = this.parserSpel.parseExpression(redisCache.unless());
StandardEvaluationContext context = new StandardEvaluationContext();
context.setVariable("result", obj);
if (expression.getValue(context, Boolean.class)) {
return obj;
}
}
this.redisTemplate.opsForValue().set(keyName.toString(), obj, redisCache.time(), redisCache.unit());
return obj;
}
}