Spring学习笔记05-AOP(二)

一、切面的优先级

基于Spring学习进度-04-AOP(一)案例代码,新建QiemianYouxianji.java

package aop;


import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Component;

@Order(1)
@Aspect
@Component
public class QiemianYouxianji {
    
    @Before("Qiemian.declareExpression()")
    public void youxianji() {
         System.out.println("我最快");
    }

}
QiemianYouxianji.java

二、重用切点表达式

重写Qiemian.java

package aop;

import java.util.Arrays;
import java.util.List;

import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.After;
import org.aspectj.lang.annotation.AfterReturning;
import org.aspectj.lang.annotation.AfterThrowing;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Component;

//把这个类声明为一个切面,放到IOC容器,再声明为一个切面
@Order(2)
@Aspect
@Component
public class Qiemian {
    
    //定义一个方法用于声明切入点表达式,一般该方法不需注入其他方法
    //使用@Pointcut声明切入点表达式,后面只需调用该方法即可
    @Pointcut("execution(* aop.*.*(..))")
    public void declareExpression() {
        
    }

    //声明该方法是一个前置通知
    //@Before("execution(public int aop.Yunsuan.*(int,int))")
    //@Before("execution(* aop.*.*(int,int))")
    @Before("declareExpression()")
    public void before(JoinPoint joinpoint) {
        String name=joinpoint.getSignature().getName();
        List<Object> args=Arrays.asList(joinpoint.getArgs());
         System.out.println(name+" begin "+args);
    }
    
    //后置通知,目标方法执行后(无论异常)
    @After("declareExpression()")
    public void after(JoinPoint joinpoint) {
        String name=joinpoint.getSignature().getName();
        //不能返回目标方法执行的结果
        //List<Object> args=Arrays.asList(joinpoint.getArgs());
         System.out.println(name+" end ");
    }
    
    //返回通知,在方法正常结束后执行,,可以访问到方法的返回值
    @AfterReturning(value="declareExpression()",
            returning="result")
    public void afterReturning(JoinPoint joinpoint,Object result) {
        String name=joinpoint.getSignature().getName();
        System.out.println(name+" end with " + result);
    }
    
    //异常通知,在方法出现异常时执行,可以访问到异常对象
    @AfterThrowing(value="declareExpression()",
            throwing="e")
    public void afterThrowing(JoinPoint joinpoint,Exception e) {
        String name=joinpoint.getSignature().getName();
        System.out.println(name+" exception " + e);
    }
    
    //环绕通知,需携带ProceedingJoinPoint类型的参数,必须有返回值
    @Around("declareExpression()")
    public Object around(ProceedingJoinPoint pdj) {
        Object result=null;
        String name=pdj.getSignature().getName();
        //执行目标方法
        try {
            //前置通知
            System.out.println(name+" begin with " + Arrays.asList(pdj.getArgs()));
            result = pdj.proceed();
            //后置通知
            System.out.println(name+" end with " + Arrays.asList(pdj.getArgs()));
        } catch (Throwable e) {
            // TODO 自动生成的 catch 块
            //异常通知
            System.out.println(name+" exception " + e);
            throw new RuntimeException(e);
        }
        //后置通知
        System.out.println(name+" end ");
        return result;
    }
}
Qiemian.java

原文地址:https://www.cnblogs.com/MoooJL/p/12676066.html