《Spring Recipes》第三章笔记2:Declaring Aspects

 《Spring Recipes》第三章笔记2:Declaring Aspects


Spring容器支持的AspectJ注解:@Aspect,@Before,@After,@AfterReturning,@AfterThrowing,@Around。
注意:切面必须让Spring容器管理(使用注解或者在配置文件中声明切面)才能生效。

1、@Aspect:声明一个切面。
2、@Before:定义在切入点之前执行特定代码。
@Aspect
public class CalculatorLoggingAspect {
  private Log log = LogFactory.getLog(this.getClass());
  @Before("execution(* ArithmeticCalculator.add(..))")
  public void logBefore() {
    log.info("The method add() begins");
  }
}

可以通知方法中添加JoinPoint类型的参数,获取JoinPoint的信息:
@Aspect
public class CalculatorLoggingAspect {
... ...
  @Before("execution(* *.*(..))")
  public void logBefore(JoinPoint joinPoint) {
    log.info("The method " + joinPoint.getSignature().getName()+ "() begins with " + Arrays.toString(joinPoint.getArgs()));
  }
}


3、@After:定义在切入点之后 执行特定代码,无论切入点是成功返回还是抛出异常。
@Aspect
public class CalculatorLoggingAspect {
...
  @After("execution(* *.*(..))")
  public void logAfter(JoinPoint joinPoint) {
    log.info("The method " + joinPoint.getSignature().getName()
    + "() ends");
  }
}


4、@AfterReturning:定义在切入点成功返回后执行特定代码。
@Aspect
public class CalculatorLoggingAspect {
... ...
  @AfterReturning("execution(* *.*(..))")
  public void logAfterReturning(JoinPoint joinPoint) {
  log.info("The method " + joinPoint.getSignature().getName()+ "() ends");
  }
}

可以在@ AfterReturning注解中添加returning,在通知中添加Object类型的参数获取方法的返回信息:
@Aspect
public class CalculatorLoggingAspect {
... ...
  @AfterReturning(pointcut = "execution(* *.*(..))",
                  returning = "result")
  public void logAfterReturning(JoinPoint joinPoint, Object result) {
    log.info("The method " + joinPoint.getSignature().getName()+ "() ends with " + result);
  }
}


5、@AfterThrowing:定义在切入点抛出异常后执行特定代码,可以指定抛出的异常类型。
@Aspect
public class CalculatorLoggingAspect {
... ...
  @AfterThrowing("execution(* *.*(..))")
  public void logAfterThrowing(JoinPoint joinPoint) {
    log.error("An exception has been thrown in "+ joinPoint.getSignature().getName() + "()");
  }
}

可以通过在 @AfterThrowing 中添加throwing获取异常,在通知中添加Throwable类型的参数:
@Aspect
public class CalculatorLoggingAspect {
... ...
  @AfterThrowing(pointcut = "execution(* *.*(..))",
                 throwing = "e")
  public void logAfterThrowing(JoinPoint joinPoint, Throwable e) {
    log.error("An exception " + e + " has been thrown in "+ joinPoint.getSignature().getName() + "()");
  }
}

可以通过在通知中指定异常类型,来只捕获特定类型的异常:
@Aspect
public class CalculatorLoggingAspect {
... ...
  @AfterThrowing(pointcut = "execution(* *.*(..))",
                 throwing = "e")
  public void logAfterThrowing(JoinPoint joinPoint,IllegalArgumentException e) {
    log.error("Illegal argument " + Arrays.toString(joinPoint.getArgs())+ " in " + joinPoint.getSignature().getName() + "()");
  }
}


6、@Around:对切入点具有完全的控制,可以在一个通知中定义上面5中类型的通知。
@Around通知的参数必须为ProceedingJoinPoint类型。
@Aspect
public class CalculatorLoggingAspect {
...
@Around("execution(* *.*(..))")
public Object logAround(ProceedingJoinPoint joinPoint) throws Throwable {
  log.info("The method " + joinPoint.getSignature().getName()+ "() begins with " + Arrays.toString(joinPoint.getArgs()));
  try {
    Object result = joinPoint.proceed();
    log.info("The method " + joinPoint.getSignature().getName()+ "() ends with " + result);
    return result;
   } catch (IllegalArgumentException e) {
    log.error("Illegal argument "+ Arrays.toString(joinPoint.getArgs()) + " in "+ joinPoint.getSignature().getName() + "()");
    throw e;
   }
 }
}



你可能感兴趣的:(spring)