Aop @Before @AfterReturning @After @AfterThrowing 简单实现

@Aspect
@Component
public class TransactionAspect {
    
    /**
     * 定义切入点:切入点的名称是:pc1()
     *  使用表达式来定位要拦截的方法,常用的表达式:
     *  1)execution():精确定位到方法
     *  2)within():精确定位到类(类中所有方法)
     *  3)@annotation():精确定位标注了指定注解的方法
     * */
    @Pointcut("execution(public * com.wzl.service..*.*(..))")
    public void pc1() {}
    
    // 前置通知
    @Before("pc1()")
    public void test1(JoinPoint jp) {
        String md = jp.getSignature().toLongString();
        Object[] args = jp.getArgs();
        System.out.println(" ==> 方法名:" + md);
        System.out.println(" ==> 参数值:" + Arrays.toString(args));
        
        System.out.println("==== 事务开启 ...");
    }
    
    // 后置通知
    @AfterReturning(pointcut="pc1()", returning="ret")
    public void test2(Object ret) {
        System.out.println(" ==> 方法返回值:" + ret);
        System.out.println("==== 事务提交 ...");
    }
    
    // 异常通知
    @AfterThrowing(pointcut="pc1()", throwing="ex")
    public void test3(Throwable ex) {
        String msg = String.format(" ==> 方法异常:%s(%s)", ex.getClass().getName(), ex.getMessage());
        System.out.println(msg);
        
        System.out.println("==== 事务回滚 ...");
    }
    
    // 最终通知
    @After("pc1()")
    public void test4() {
        System.out.println("==== 关闭连接 ...");
    }
    
    /**
     * 环绕通知:自定义通知
     *  必须有返回值:Object
     *  必须有参数:ProceedingJoinPoint
     *  必须抛出异常:throws Throwable
     */
//  @Around("pc1()")
    public Object test5(ProceedingJoinPoint pjp) throws Throwable {
        
        try {
            System.out.println("----------- 前置通知");
            
            Object ret = pjp.proceed(); //调用目标对象的方法
            
            System.out.println("----------- 后置通知");
            
            return ret;
            
        } catch(Throwable ex) {
            System.out.println("----------- 异常通知");
            throw ex;
        } finally {
            System.out.println("----------- 最终通知");
        }
    }
    
    
}

推荐阅读更多精彩内容