spring注解切面封装并解析spring的EL表达式自定义缓存注解

学习了自定义缓存注解,在这里做下记录
以下代码简单的实现了一个缓存的流程:查询数据时先查询redis缓存,缓存中没有就去Mysql中取出并缓存到redis中。
这次要替代一个以前从来没遇到过的点,就是spring的EL表达式的解析

/**
     * 使用SPEL进行key的解析
     *
     * @param expressionString 表达式字符串
     * @param method           方法对象,用于获取参数名
     * @param args             方法的参数值
     * @return
     */
    private String parseExpression(String expressionString, Method method, Object[] args) {
        //获取被拦截方法参数名列表
        LocalVariableTableParameterNameDiscoverer discoverer = new LocalVariableTableParameterNameDiscoverer();
        String[] paramNameArr = discoverer.getParameterNames(method);
        //SPEL解析
        ExpressionParser parser = new SpelExpressionParser();
        StandardEvaluationContext context = new StandardEvaluationContext();
        for (int i = 0; i < paramNameArr.length; i++) {
            context.setVariable(paramNameArr[i], args[i]);
        }
        String result = parser.parseExpression(expressionString).getValue(context, String.class);
        return result;
    }

基于spring注解切面实现的redis切面缓存

import com.annotation.MyAnnotation;
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.core.DefaultParameterNameDiscoverer;
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.spel.standard.SpelExpressionParser;
import org.springframework.expression.spel.support.StandardEvaluationContext;
import org.springframework.stereotype.Component;

import java.lang.reflect.Method;

@Aspect
@Component
public class MyAnnotationAspect {

    @Autowired
    private RedisTemplate<Object, Object> redisTemplate;

    @Around("@annotation(com.annotation.MyAnnotation)")
    public Object MyAnnotation(ProceedingJoinPoint proceedingJoinPoint) throws Throwable {
        System.out.println("进入注解片面~~~~~~~~");

        //疑问key的内容-根据方法参数1,获取到方法注解里面的key内容-反射知识
        MethodSignature signature = (MethodSignature) proceedingJoinPoint. getSignature();
        Method method = proceedingJoinPoint.getTarget().getClass().getMethod(signature.getName(),signature.getMethod().getParameterTypes());
        MyAnnotation myAnnotation = method.getAnnotation(MyAnnotation.class);
        //反射技术-JDK最底层的API
        String keyEL = myAnnotation.key();
        System.out.println("注解中key的值keyEL:"+keyEL);
        // 2.拿到方法的参数名和参数值, 方便解析key表达式
        // 创建解析器
        ExpressionParser parser = new SpelExpressionParser();
        Expression expression = parser. parseExpression (keyEL);
        //设置解析上下文(有哪些占位荷,以及每种占位符的值-根据方法的参数名和参数值
        EvaluationContext context = new StandardEvaluationContext();
        //参歌
        Object [] args = proceedingJoinPoint. getArgs();
        String [] parameterNames=new DefaultParameterNameDiscoverer().getParameterNames(method);
        for (int i =0; i < parameterNames.length; i++){
            System.out.println("参数名:"+ parameterNames[i]+"; 参数值:"+args[i]);
            context.setVariable(parameterNames[i],args[i]);
        }
        // T0D0 3,解析表达式,生成最终的key
        String key = expression.getValue(context).toString();
        //1 redis缓存一性能需求-查询并发量
        System.out.println("缓存中有数据: "+key);
        Object o = redisTemplate.opsForValue().get(key);
        if (o != null){
            //缓存中有数据直接返回数据
            return o;
        }

        Object proceed = proceedingJoinPoint.proceed();

        if (proceed != null){
            //缓存数据
            redisTemplate.opsForValue().set(key,proceed);
        }

        System.out.println("结束注解片面~~~~~~~~");

        return proceed;
    }


}

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

@Target(value = ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface MyAnnotation {

    String key();

}

@MyAnnotationAspect(key = "#argid") 
@Override
    public Object testAnnotation(String argid,String arg01){

        System.out.println("testAnnotation: argid="+argid+"; arg01="+arg01);
        AdminUser byname = null;
        AdminUser byname = adminUserMapper.findByname(argid);

        return byname;
    }
  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值