Redisキャッシュカスタム注記

4953 ワード

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;
}