spring注解切⾯封装并解析spring的EL表达式⾃定义缓存注解
学习了⾃定义缓存注解,在这⾥做下记录
以下代码简单的实现了⼀个缓存的流程:查询数据时先查询redis缓存,缓存中没有就去Mysql中取出并缓存到redis中。
el表达式获取值
这次要替代⼀个以前从来没遇到过的点,就是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 = ParameterNames(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.flect.MethodSignature;
import org.springframework.beans.factory.annotation.Autowired;
import DefaultParameterNameDiscoverer;
import org.RedisTemplate;
import pression.EvaluationContext;
import pression.Expression;
import pression.ExpressionParser;
import pression.spel.standard.SpelExpressionParser;
import pression.spel.support.StandardEvaluationContext;
import org.springframework.stereotype.Component;
import flect.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 = Target().getClass().Name(),Method().getParameterTypes());        MyAnnotation myAnnotation = Annotation(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 = Value(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;
}

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。