使Spring Boot 自定义注解支持EL表达式

本文介绍了如何在SpringBoot中创建一个自定义注解`DistributeExceptionHandler`,该注解用于标记方法并处理这些方法抛出的异常。注解包含一个EL表达式参数`attachmentId`,并在切面`DistributeExceptionAspect`中通过`@AfterThrowing`处理异常。文章还展示了如何使用`ExpressionEvaluator`解析EL表达式,从方法参数中获取`attachmentId`值。

使Spring Boot 自定义注解支持EL表达式_lijian0706的博客-CSDN博客_注解使用el表达式自定义注解自定义DistributeExceptionHandler注解,该注解接收一个参数attachmentId。该注解用在方法上,使用该注解作为切点,实现标注该注解的方法抛异常后的统一处理。/** * @Author: Lijian * @Date: 2019-09-06 09:26 */@Target(ElementType.METHOD)@Retention(Rete...https://blog.csdn.net/u010721764/article/details/100584272

  • 自定义DistributeExceptionHandler注解,该注解接收一个参数attachmentId
  • 该注解用在方法上,使用该注解作为切点,实现标注该注解的方法抛异常后的统一处理。
/**
 * @Author: Lijian
 * @Date: 2019-09-06 09:26
 */
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface DistributeExceptionHandler {
    String attachmentId();
}
  • 使用方法:
  • @DistributeExceptionHandler(attachmentId = "#test.id") public void test(Test test){ }

=====

Aspect代码

  • 拦截DistributeExceptionHandler注解作为切点
  • 使用@AfterThrowing处理异常情况
  • **
     * @Author: Lijian
     * @Date: 2019-09-06 09:22
     */
    @Component
    @Aspect
    @Slf4j
    public class DistributeExceptionAspect {
    
        @Autowired
        private AttachmentContentClient attachmentContentClient;
    
        @Autowired
        private DistTaskService distTaskService;
    
        private ExpressionEvaluator<String> evaluator = new ExpressionEvaluator<>();
    
        @Pointcut("@annotation(DistributeExceptionHandler)")
        private void exceptionHandleMethod() {
    
        }
    
        @AfterThrowing(value = "exceptionHandleMethod()", throwing = "ex")
        public void doThrowing(JoinPoint joinPoint, Throwable ex) {
            log.error("捕获异常");
            String attachmentId = getAttachmentId(joinPoint); // 获取
            // 处理异常情况下的业务
        }
    
        private DistributeExceptionHandler getDistributeExceptionHandler(JoinPoint joinPoint){
            MethodSignature signature = (MethodSignature) joinPoint.getSignature();
            Method method = signature.getMethod();
            return method.getAnnotation(DistributeExceptionHandler.class);
        }
    
        private String getAttachmentId(JoinPoint joinPoint) {
            DistributeExceptionHandler handler = getDistributeExceptionHandler(joinPoint);
            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.condition(handler.attachmentId(), methodKey, evaluationContext, String.class);
        }
    }
    

    为注解添加Spring EL支持

  • ExpressionRootObject
  • /**
     * @Author: Lijian
     * @Date: 2019-09-06 09:26
     */
    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;
        }
    }

  • ExpressionEvaluator
  • /**
     * @Author: Lijian
     * @Date: 2019-09-06 09:26
     */
    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;
        }
    }

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值