AspectJ通知类型简介

88 阅读2分钟

AspectJ是一种基于Java编程语言的面向切面编程(AOP)框架。它通过在程序中定义切面(Aspect),在特定的连接点(Join Point)上插入通知(Advice)来实现横切关注点的模块化。通知是AspectJ中的核心概念之一,它定义了切面在何时、在何地执行的逻辑。

AspectJ提供了五种通知类型:前置通知(Before Advice)、后置通知(After Advice)、返回通知(After Returning Advice)、异常通知(After Throwing Advice)和环绕通知(Around Advice)。接下来,我们将一一介绍这五种通知类型,并提供相应的示例代码。

  1. 前置通知(Before Advice): 前置通知在目标方法执行前执行,通常用于插入额外的逻辑,例如参数验证或日志记录。

示例代码:

public aspect BeforeAdviceAspect {
    before(): execution(* com.example.MyClass.myMethod(..)) {
        System.out.println("前置通知:目标方法执行前");
    }
}

public class MyClass {
    public void myMethod() {
        System.out.println("目标方法执行");
    }
}
  1. 后置通知(After Advice): 后置通知在目标方法执行后执行,无论方法是否抛出异常。通常用于清理资源或记录执行结果等。

示例代码:

public aspect AfterAdviceAspect {
    after(): execution(* com.example.MyClass.myMethod(..)) {
        System.out.println("后置通知:目标方法执行后");
    }
}

public class MyClass {
    public void myMethod() {
        System.out.println("目标方法执行");
    }
}
  1. 返回通知(After Returning Advice): 返回通知在目标方法成功执行并返回结果后执行。通常用于在方法返回后执行某些操作,如修改返回值或记录返回结果。

示例代码:

public aspect AfterReturningAdviceAspect {
    after() returning(Object result): execution(* com.example.MyClass.myMethod(..)) {
        System.out.println("返回通知:目标方法成功执行并返回结果");
        System.out.println("返回结果:" + result);
    }
}

public class MyClass {
    public int myMethod() {
        System.out.println("目标方法执行");
        return 42;
    }
}
  1. 异常通知(After Throwing Advice): 异常通知在目标方法抛出异常后执行。通常用于处理异常或记录异常信息。

示例代码:

public aspect AfterThrowingAdviceAspect {
    after() throwing(Exception e): execution(* com.example.MyClass.myMethod(..)) {
        System.out.println("异常通知:目标方法抛出异常");
        System.out.println("异常信息:" + e.getMessage());
    }
}

public class MyClass {
    public void myMethod() throws Exception {
        System.out.println("目标方法执行");
        throw new Exception("发生异常");
    }
}
  1. 环绕通知(Around Advice): 环绕通知可以在目标方法执行前后插入自定义的逻辑。通过在通知中调用proceed()方法,可以控制目标方法的执行。

示例代码:

public aspect AroundAdviceAspect {
    Object around(): execution(* com.example.MyClass.myMethod(..)) {
        System.out.println("环绕通知:目标方法执行前");
        Object result = null;
        try {
            result = proceed(); // 执行目标方法
            System.out.println("环绕通知:目标方法执行后");
        } catch (Exception e) {
            System.out.println("环绕通知:目标方法抛出异常");
            System.out.println("异常信息:" + e.getMessage());
        }
        return result;
    }
}

public class MyClass {
    public void myMethod() throws Exception {
        System.out.println("目标方法执行");
        throw new Exception("发生异常");
    }
}