原创

AOP注解配合EL表达式

import org.springframework.aop.support.AopUtils;
import org.springframework.context.expression.AnnotatedElementKey;
import org.springframework.context.expression.CachedExpressionEvaluator;
import org.springframework.context.expression.MethodBasedEvaluationContext;
import org.springframework.core.DefaultParameterNameDiscoverer;
import org.springframework.core.ParameterNameDiscoverer;
import org.springframework.expression.EvaluationContext;
import org.springframework.expression.Expression;

import java.lang.reflect.Method;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

/**
* TODO: 描述
*
* @author 木杉
* @classname ExpressionEvaluator
* @date 2022/11/21 16:58
*/
public class ExpressionEvaluator<T> extends CachedExpressionEvaluator {
private final ParameterNameDiscoverer paramNameDiscoverer = new DefaultParameterNameDiscoverer();
private final Map<ExpressionKey, Expression> conditionCache = new ConcurrentHashMap<>(64);
private final Map<AnnotatedElementKey, Method> targetMethodCache = new ConcurrentHashMap<>(64);


public EvaluationContext createEvaluationContext(Object object, Class<?> targetClass, Method method, Object[] args) {
Method targetMethod = getTargetMethod(targetClass, method);
ExpressionRootObject root = new ExpressionRootObject(object, args);
return new MethodBasedEvaluationContext(root, targetMethod, args, this.paramNameDiscoverer);
}


public T condition(String conditionExpression, AnnotatedElementKey elementKey, EvaluationContext evalContext, Class<T> clazz) {
return getExpression(this.conditionCache, elementKey, conditionExpression).getValue(evalContext, clazz);
}

private Method getTargetMethod(Class<?> targetClass, Method method) {
AnnotatedElementKey methodKey = new AnnotatedElementKey(method, targetClass);
Method targetMethod = this.targetMethodCache.get(methodKey);
if (targetMethod == null) {
targetMethod = AopUtils.getMostSpecificMethod(method, targetClass);
if (targetMethod == null) {
targetMethod = method;
}
this.targetMethodCache.put(methodKey, targetMethod);
}
return targetMethod;
}
}
/**
* TODO: 描述
*
* @author 黄雁彬
* @classname ExpressionRootObject
* @date 2022/11/21 16:59
*/
public class ExpressionRootObject {

private final Object object;
private final Object[] args;

public ExpressionRootObject(Object object, Object[] args) {
this.object = object;
this.args = args;
}

public Object getObject() {
return object;
}

public Object[] getArgs() {
return args;
}
}
/**
* TODO: 描述
*
* @author 黄雁彬
* @classname UserCheck
* @date 2022/11/21 17:03
*/
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.METHOD})
@Documented
public @interface UserCheck {

/**
* 用户id(el表达式)
* @return
*/
String userId() default "";

/**
* 验证token与用户的合法性
* @return
*/
boolean tokenCheck() default false;
}
import lombok.extern.slf4j.Slf4j;
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.context.expression.AnnotatedElementKey;
import org.springframework.expression.EvaluationContext;
import org.springframework.stereotype.Component;

import java.lang.reflect.Method;

/**
* TODO: 描述
*
* @author 黄雁彬
* @classname UserCheckAspect
* @date 2022/11/21 17:05
*/
@Aspect
@Slf4j
@Component
public class UserCheckAspect {

private static final ExpressionEvaluator<Integer> EVALUATOR = new ExpressionEvaluator<>();
@Autowired
private AppointCheckCoreHandler appointCheckCoreHandler;

@Around("@annotation(userCheck)")
public Object checkUser(ProceedingJoinPoint point, UserCheck userCheck) throws Throwable {
String el = userCheck.userId();
Assert.noBlank(el, "用户id不能为空");
//获取到用户id
Integer userId = this.evalLockParam(point, el);

//校验用户合法性
appointCheckCoreHandler.validUser(userId);

return point.proceed();
}

/**
* TODO: 解析EL表达式
*
* @param point 切入点
* @param el 需要解析的EL表达式
* @return 解析出的值
* @methodName evalLockParam
* @date 2022/11/21 17:12
* @author 黄雁彬
*/
private Integer evalLockParam(ProceedingJoinPoint point, String el) {
MethodSignature ms = (MethodSignature) point.getSignature();
Method method = ms.getMethod();
Object[] args = point.getArgs();
Object target = point.getTarget();
Class<?> targetClass = target.getClass();
EvaluationContext context = EVALUATOR.createEvaluationContext(target, target.getClass(), method, args);
AnnotatedElementKey elementKey = new AnnotatedElementKey(method, targetClass);
return EVALUATOR.condition(el, elementKey, context, Integer.class);
}


}


正文到此结束
该篇文章的评论功能已被站长关闭