一、知识点
在编写AspectJ aspect时,可以直接在通知注解中嵌入切入点表达式。但是,相同的切入点表达式可能在多个通知中重复。
和其它许多AOP实现一样,AspectJ也允许独立地定义切入点,在多个通知中重用。
二、代码示例
在AspectJ aspect中,切入点可以声明为一个带有@Pointcut注解的简单方法。切入点的方法体通常为空,因为将切入点定义与应用程序逻辑混合在一起是不合理的。切入点方法的访问修饰符控制切入点的可见性。其他通知可以用方法名称引用这个切入点。
package com.codeproject.jackie.springrecipesnote.springaop; import java.util.Arrays; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; 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; /** * @author jackie * */ @Aspect public class CalculatorLoggingAspect { private Log log = LogFactory.getLog(this.getClass()); @Pointcut("execution(* *.*(..))") private void loggingOperation() { } @Before("loggingOperation()") public void logBefore(JoinPoint joinPoint) { log.info("The method " + joinPoint.getSignature().getName() + "() begins with " + Arrays.toString(joinPoint.getArgs())); } @After("loggingOperation()") public void logAfter(JoinPoint joinPoint) { log.info("The method " + joinPoint.getSignature().getName() + "() ends"); } @AfterReturning(pointcut = "loggingOperation())", returning = "result") public void logAfterReturning(JoinPoint joinPoint, Object result) { log.info("The method " + joinPoint.getSignature().getName() + "() ends with " + result); } @AfterThrowing(pointcut = "loggingOperation())", throwing = "e") public void logAfterThrowing(JoinPoint joinPoint, Throwable e) { log.error("An exception " + e + " has been thrown in " + joinPoint.getSignature().getName() + "()"); } @Around("loggingOperation()") 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; } } }
通常,如果切入点在多个aspect之间共享,最好将它们集中到一个公共类中。在这种情况下,它们必须声明为public。
package com.codeproject.jackie.springrecipesnote.springaop; import org.aspectj.lang.annotation.Aspect; import org.aspectj.lang.annotation.Pointcut; /** * @author jackie * */ @Aspect public class CalculatorPointcuts { @Pointcut("execution(* *.*(..))") public void loggingOperation() { } }
当引用这个切入点时,必须包含类名。如果类不在与这个aspect相同的包中,还必须包含包名。
@Before("CalculatorPointcuts.loggingOperation()") public void logBefore(JoinPoint joinPoint) { log.info("The method " + joinPoint.getSignature().getName() + "() begins with " + Arrays.toString(joinPoint.getArgs())); } @After("CalculatorPointcuts.loggingOperation()") public void logAfter(JoinPoint joinPoint) { log.info("The method " + joinPoint.getSignature().getName() + "() ends"); } @AfterReturning(pointcut = "CalculatorPointcuts.loggingOperation())", returning = "result") public void logAfterReturning(JoinPoint joinPoint, Object result) { log.info("The method " + joinPoint.getSignature().getName() + "() ends with " + result); } @AfterThrowing(pointcut = "CalculatorPointcuts.loggingOperation())", throwing = "e") public void logAfterThrowing(JoinPoint joinPoint, Throwable e) { log.error("An exception " + e + " has been thrown in " + joinPoint.getSignature().getName() + "()"); } @Around("CalculatorPointcuts.loggingOperation()") 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; } }