// 自定義註解
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
public @interface LogExecution {
}
@Aspect // 切面類
@Order(1000) // 數字越小,優先順序越高
@Component // 也要註冊到容器
public class LoggingAspect {
// 定義切點
@Pointcut("execution(* com.example.service.*.*(..))")
public void serviceMethods() {}
// 前通知
@Before("serviceMethods()")
public void logBefore(JoinPoint joinPoint) {
System.out.println("Executing method...");
System.out.println("Before method: " + joinPoint.getSignature());
}
// 後通知
@After("serviceMethods()")
public void logAfter(JoinPoint joinPoint) {
System.out.println("Method execution completed.");
}
// 返回通知
@AfterReturning(pointcut = "serviceMethods()", JoinPoint joinPoint, returning = "result")
public void logAfterReturning(Object result) {
System.out.println("Method returned: " + result);
}
// 異常通知
@AfterThrowing(pointcut = "serviceMethods()", throwing = "ex")
public void logAfterThrowing(Throwable ex) {
System.out.println("Method threw an exception: " + ex);
}
// 環繞通知(四合一通知)
@Around("serviceMethods()")
public Object logAround(ProceedingJoinPoint joinPoint) throws Throwable {
System.out.println("Before..."); // 前通知
Object[] args = joinPoint.getArgs(); // 引數
try {
Object result = joinPoint.proceed(); // 執行目標方法
System.out.println("AfterReturning"); // 返回通知
} catch {
System.out.println("AfterThrowing..."); // 異常通知
} finally {
System.out.println("After..."); // 後通知
}
return result;
}
// 使用自定義註解的通知
@Before("@annotation(LogExecution)")
public void logBeforeAnnotatedMethod() {
System.out.println("Executing annotated method...");
}
}