Redis缓存自定义注解

package com.my.cache;

import java.lang.reflect.Method;
import org.aspectj.lang.JoinPoint;
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.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.EnableAspectJAutoProxy;
import org.springframework.core.LocalVariableTableParameterNameDiscoverer;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.expression.EvaluationContext;
import org.springframework.expression.Expression;
import org.springframework.expression.ExpressionParser;
import org.springframework.expression.common.TemplateParserContext;
import org.springframework.expression.spel.standard.SpelExpressionParser;
import org.springframework.expression.spel.support.StandardEvaluationContext;

@EnableAspectJAutoProxy
@Aspect
@Configuration
public class CacheAop {

  static final Logger log = LoggerFactory.getLogger(" com.my.cache.CacheAop");


  @Autowired
  private RedisTemplate redisTemplate;

  @Pointcut(value = "@annotation(com.my.cache.RedisCache))")
  public void pointCut() {
  }

  @Around("pointCut()")
  public Object around(ProceedingJoinPoint joinPoint) throws Throwable {
    Method method = null;
    /**  获取参数列表  **/
    Object[] args = joinPoint.getArgs();
    log.info("参数列表:*******" + args);

    /**  获取方法对象  **/
    try {
      MethodSignature signature = (MethodSignature)joinPoint.getSignature();
      method = signature.getMethod();
    } catch (Exception e) {
      log.error("获取方法对象异常:" + e);
    }

    /**  获取Key 值 **/
    String key = null;
    Object process = null;
    try {
      RedisCache annotation = method.getAnnotation(RedisCache.class);
      String ss = annotation.key();
      key = parseKey(method, args, ss);
    } catch (Exception e) {
      log.error("获取key异常:" + e);
    }
    log.info("key:**************" + key);
    /** 获取Redis缓存  **/
    process = getCache(key);
    if (process != null) {
      return process;
    }
    /** 执行过程  **/
    process = args.length > 0 ? joinPoint.proceed(args) : joinPoint.proceed();

    /** 放入缓存 Redis **/
    if (process != null) {
      putCache(key, process);
    }

    return process;
  }


  public Object getCache(String id) {
    Object ss = redisTemplate.opsForValue().get(id);
    if (ss == null || ss.equals("")) {
      return null;
    }
    log.info("缓存命中***" + ss);
    return ss;
  }

  public void putCache(String id, Object result) {
    log.info("放入缓存key******" + id + "**value**" + result);
    redisTemplate.opsForValue().set(id, result);
  }


  /**
   * 参数2为方法参数值,参数3为注解中某个属性的值,若含有#则为一个表达式 待解决,解析#user.id的问题
   *
   * @param method
   * @param argValues
   * @param expr
   */
  private String parseKey(Method method, Object[] argValues, String expr) {
    if (expr.contains("#")) {
      String paramName = expr.substring(expr.indexOf('#') + 1);
      // 获取方法参数名列表
      LocalVariableTableParameterNameDiscoverer discoverer = new LocalVariableTableParameterNameDiscoverer();
      String[] paramNames = discoverer.getParameterNames(method);
      for (int i = 0; i < paramNames.length; i++) {
        if (("{" + paramNames[i] + "}").equals(paramName)) {
          return expr.substring(0, expr.indexOf('#')) + argValues[i].toString();
        }
      }
      throw new IllegalArgumentException("解析不了该参数,错误参数表达式");
    } else {
      // 不需要解析,直接返回
      return expr;
    }
  }


  public static void main(String[] args) {
    String template = "${user},早上好";//设置文字模板,其中#{}表示表达式的起止,#user是表达式字符串,表示引用一个变量。
    ExpressionParser paser = new SpelExpressionParser();//创建表达式解析器
    //通过evaluationContext.setVariable可以在上下文中设定变量。
    EvaluationContext context = new StandardEvaluationContext();
    context.setVariable("user", "黎明");
    //解析表达式,如果表达式是一个模板表达式,需要为解析传入模板解析器上下文。
    Expression expression = paser.parseExpression(template, new TemplateParserContext());

    System.out.println(expression.getValue(context, String.class));

  }
}
----------------------------------缓存注解---------------------
package com.my.cache;

import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface RedisCache {

  String key();

  int expire() default -1;
}

你可能感兴趣的:(redis)