先贴两个工具类: 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; } }
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; 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 getValue(String conditionExpression, AnnotatedElementKey elementKey, EvaluationContext evalContext, Class<T> clazz) { return getExpression(this.conditionCache, elementKey, conditionExpression).getValue(evalContext, clazz); } public void setValue(String conditionExpression, AnnotatedElementKey elementKey, EvaluationContext evalContext, Object value) { getExpression(this.conditionCache, elementKey, conditionExpression).setValue(evalContext, value); } 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; } }
一个aop基础类:
import org.aspectj.lang.JoinPoint; import org.aspectj.lang.reflect.MethodSignature; import org.springframework.context.expression.AnnotatedElementKey; import org.springframework.core.annotation.AnnotationUtils; import org.springframework.expression.EvaluationContext; import java.lang.annotation.Annotation; import java.lang.reflect.Method; import java.lang.reflect.ParameterizedType; import java.util.Arrays; import java.util.List; /** * 类 描 述:资源切片的基础类 * 创建时间:2021/12/21 上午9:30 * 创 建 :gzc */ public class BaseResourceAspect<T extends Annotation> { private ExpressionEvaluator<String> evaluator = new ExpressionEvaluator<>(); //只获取方法上的注解信息 没有获取类上的信息 /*public T getAnnotion(JoinPoint joinPoint){ MethodSignature signature = (MethodSignature) joinPoint.getSignature(); Method method = signature.getMethod(); Class<T> actualTypeArgument = (Class<T>) ((ParameterizedType) getClass().getGenericSuperclass()).getActualTypeArguments()[0]; return method.getAnnotation(actualTypeArgument); }*/ public T getAnnotion(JoinPoint pj) { // 获取切入的 Method MethodSignature joinPointObject = (MethodSignature) pj.getSignature(); Method method = joinPointObject.getMethod(); Class<T> actualTypeArgument = (Class<T>) ((ParameterizedType) getClass().getGenericSuperclass()).getActualTypeArguments()[0]; boolean flag = method.isAnnotationPresent(actualTypeArgument); if (flag) { T annotation = method.getAnnotation(actualTypeArgument); return annotation; } else { // 如果方法上没有注解,则搜索类上是否有注解 T classAnnotation = AnnotationUtils.findAnnotation(joinPointObject.getMethod().getDeclaringClass(), actualTypeArgument); if (classAnnotation != null) { return classAnnotation; } else { return null; } } } /** * el 取值 * @param joinPoint * @return */ public String getValue(JoinPoint joinPoint,String el) { if (joinPoint.getArgs() == null) { return null; } EvaluationContext evaluationContext = evaluator.createEvaluationContext(joinPoint.getTarget(), joinPoint.getTarget().getClass(), ((MethodSignature) joinPoint.getSignature()).getMethod(), joinPoint.getArgs()); AnnotatedElementKey methodKey = new AnnotatedElementKey(((MethodSignature) joinPoint.getSignature()).getMethod(), joinPoint.getTarget().getClass()); return evaluator.getValue(el, methodKey, evaluationContext, String.class); } /** * el 设置值 * @param joinPoint * @param value */ public Object[] setValue(JoinPoint joinPoint,String el,Object value) { Object[] args = joinPoint.getArgs(); List<String> argNames = Arrays.asList(((MethodSignature) joinPoint.getSignature()).getParameterNames()); String arg = el.replace("#", "").split("\\.")[0]; int index = argNames.indexOf(arg); if (index < 0){ return args; } if (!isPrimite(((MethodSignature) joinPoint.getSignature()).getParameterTypes()[index])) { EvaluationContext evaluationContext = evaluator.createEvaluationContext(joinPoint.getTarget(), joinPoint.getTarget().getClass(), ((MethodSignature) joinPoint.getSignature()).getMethod(), joinPoint.getArgs()); AnnotatedElementKey methodKey = new AnnotatedElementKey(((MethodSignature) joinPoint.getSignature()).getMethod(), joinPoint.getTarget().getClass()); evaluator.setValue(el, methodKey, evaluationContext, value); }else{ args[index] = value; } return args; } /** * 判断是否是基本类型 * @param clazz * @return */ private boolean isPrimite(Class clazz) { if (clazz.isPrimitive() || clazz == String.class || clazz == Byte.class || clazz == Short.class || clazz == Integer.class || clazz == Long.class || clazz == Float.class || clazz == Double.class || clazz == Boolean.class || clazz == Character.class) { return true; } else { return false; } } }
例子:
@Target({ElementType.METHOD,ElementType.TYPE}) @Retention(RetentionPolicy.RUNTIME) @Inherited @Documented public @interface ListLimit { //设置PageNo的el表达式 String pageNoEl() default ""; //设置PageSize的el表达式 String pageSizeEl() default ""; boolean check() default true; //商品库 FunctionEnum type() default FunctionEnum.ITEM_LIST; }
@Component @Aspect @Slf4j public class ListLimitAspect extends BaseResourceAspect<ListLimit> { @Resource IResourceFacade resourceFacade; @Pointcut("@annotation(com.taosj.industry.common.annotation.ur.ListLimit) || @within(com.taosj.industry.common.annotation.ur.ListLimit)") private void pointcut() { } @Around(value = "pointcut()") public Object doAround(JoinPoint joinPoint) throws Throwable { ListLimit handler = getAnnotion(joinPoint); Object[] args = new Object[0]; if(handler.check()){ FunctionPo function = resourceFacade.getFunctionByEnum(handler.type()); if (FunctionValueTypeEnum.INT.getName().equals(function.getFuncValueType())){ try { args = setValue(joinPoint,handler.pageNoEl(),1); args = setValue(joinPoint,handler.pageSizeEl(),Integer.parseInt(function.getFuncValue())); }catch (Exception e) { log.error("ListLimitAspect:setValue error value:{};top:{}",handler.pageSizeEl(),function.getFuncValue()); } } } Object obj = args != null && args.length != 0 ? ((ProceedingJoinPoint)joinPoint).proceed(args) : ((ProceedingJoinPoint)joinPoint).proceed(); // Object obj = ((ProceedingJoinPoint)joinPoint).proceed(); return obj; } }
使用例子 在方法头上加:
@ListLimit(pageNoEl = "#pageNo",pageSizeEl = "#pageSize")