美文网首页
Spring 返回通知 异常通知 环绕通知

Spring 返回通知 异常通知 环绕通知

作者: BlueSkyBlue | 来源:发表于2020-03-19 18:54 被阅读0次

    返回通知

    在方法正常返回结果后的通知。返回通知可以访问到方法的返回值。

    示例(附带返回结果的返回通知):

    @AfterReturning(value = "execution(public int com.spring.impl.ArithmeticCalculator.*(..))",
                    returning = "result")
    public void afterReturning(JoinPoint joinPoint, Object result){
        String methodName = joinPoint.getSignature().getName();
        System.out.println("The method " + methodName + " ends with " + result);
     }
    

    异常通知

    方法出现异常后返回的通知。可以访问异常的对象,并且可以指定出出现特定异常时在执行通知的代码。

    示例(附带返回的异常):

    @AfterThrowing(value = "execution(public int com.spring.impl.ArithmeticCalculator.*(..))",
                    throwing = "ex")
    public void afterThrowing(JoinPoint joinPoint, Exception ex){
        String methodName = joinPoint.getSignature().getName();
        System.out.println("The method " + methodName + " occurs exception " + ex);
    }
    

    环绕通知

    环绕通知需要携带ProceedingJoinPoint类型的参数。
    环绕通知类似于动态代理的全过程。ProceedingJoinPoint类型的参数可以决定是否执行目标方法。
    环绕通知必须有返回值。返回值必为目标方法的返回值。

    示例:

    @Around("execution(public int com.spring.impl.ArithmeticCalculator.*(..))")
    public Object aroundMethod(ProceedingJoinPoint pjd){
    
        String methodName = pjd.getSignature().getName();
        Object result = null;
        try {
            System.out.println("The method name " + methodName + " begins with " + Arrays.asList(pjd.getArgs()));
            result = pjd.proceed();
            System.out.println("The method name " + methodName + " ends with " + result);
        } catch (Throwable throwable) {
            throwable.printStackTrace();
        }
        return result;
    }
    

    Spring切面的优先级

    如果此时我们新增加一个切面

    @Aspect
    @Component
    public class ValidationAspect {
        @Before("execution(public int com.spring.impl.ArithmeticCalculator.*(..))")
        public void validateArgs(JoinPoint joinPoint){
            System.out.println("Validate " + Arrays.asList(joinPoint.getArgs()));
        }
    }
    

    它的目标目标对象和上述的一样。这样问题来了,到底先执行那一个呢?

    可以使用@Order指定切面的优先级,值越小切面的优先级越高。

    示例:
    ValidationAspect类

    @Order(1)
    @Aspect
    @Component
    public class ValidationAspect {
        @Before("execution(public int com.spring.impl.ArithmeticCalculator.*(..))")
        public void validateArgs(JoinPoint joinPoint){
            System.out.println("Validate " + Arrays.asList(joinPoint.getArgs()));
        }
    }
    

    LoggingAspect类

    @Order(2)
    @Component
    @Aspect
    public class LoggingAspect {
        @Around("execution(public int com.spring.impl.ArithmeticCalculator.*(..))")
        public Object aroundMethod(ProceedingJoinPoint pjd){
    
            String methodName = pjd.getSignature().getName();
            Object result = null;
            try {
                System.out.println("The method name " + methodName + " begins with " + Arrays.asList(pjd.getArgs()));
                result = pjd.proceed();
                System.out.println("The method name " + methodName + " ends with " + result);
            } catch (Throwable throwable) {
                throwable.printStackTrace();
            }
            return result;
        }
    }
    

    由于ValidationAspect指定了较高的优先级,所以先执行ValidationAspect中的切面。

    Spring重用切入点表达式

    定义一个方法用于定义切入点表达式。一般地,该方法中不需要添入其它代码。

    使用@PointCut来声明切入点表达式。后面的通知直接使用方法名来引用当前的切入点表达式。

    定义切入点:

    @Pointcut("execution(public int com.spring.impl.ArithmeticCalculator.*(..))")
    public void declareJointPointExpression(){
    
    }
    

    引用切入点:

    @Around("declareJointPointExpression()")
    public Object aroundMethod(ProceedingJoinPoint pjd){
        String methodName = pjd.getSignature().getName();
        Object result = null;
        try {
            System.out.println("The method name " + methodName + " begins with " + Arrays.asList(pjd.getArgs()));
            result = pjd.proceed();
            System.out.println("The method name " + methodName + " ends with " + result);
        } catch (Throwable throwable) {
            throwable.printStackTrace();
        }
        return result;
    }
    

    相关文章

      网友评论

          本文标题:Spring 返回通知 异常通知 环绕通知

          本文链接:https://www.haomeiwen.com/subject/kpolyhtx.html