在aspectj中,我们可以定义处理程序和某些注释吗?
in aspectj, can we define handler together with certain annotation?
我只想对自定义注解的方法做异常处理,
喜欢下面
@Pointcut("@annotation(com.common.CollectException) && execution(* *(..))")
public void annotationPointCutDefinition() { }
@Before("annotationPointCutDefinition() && handler(*) && args(e)")
public void logCaughtException(JoinPoint thisJoinPoint, Throwable e) {
//System.out.println(e.getClass().getCanonicalName());
System.out.println("count = " +
", " +
thisJoinPoint + " -> " +
e.getClass().getCanonicalName());
}
但是对于我自定义注解标注的方法,并没有编织logCaughtException函数
@CollectException
public void divideByZeroWithCatch(){
try{
int a = 5/0;
}
catch (ArithmeticException e){
System.out.println("Can not divide by zero");
}
}
我上面的用法有误吗?如果是这样,有人会在这里给一些建议吗?
有趣的问题。你的方面代码有几个问题:
在您的 GitHub 存储库中,您使用 @within(x.y.CollectException)
。那会拦截带注释的 classes 中的连接点,但是您的示例 class 有一个带注释的方法,class 本身没有注释。因此,该切入点永远不会匹配。
在此处的示例代码中,您使用 @annotation(x.y.CollectException)
来拦截注释方法的想法是正确的。您甚至添加了 && execution(* (..))
以将匹配限制为 execution
切入点并排除 call
切入点。否则切入点将在 AspectJ 中的每个方法触发两次(在 Spring AOP 中没有 call
连接点)。到目前为止,还不错。
但是就像call
和execution
不一样所以互斥,execution
和[=21=也是]. handler
连接点通常位于 内部 的某处( 控制流 )方法执行,但它 不是 方法执行。这也是您找到解决方案的线索。您实际上想在注释方法的控制流中限制对异常处理程序的匹配:
@Pointcut("@annotation(de.scrum_master.common.CollectException) && execution(* *(..))")
public void annotationPointCutDefinition() { }
@Before("cflow(annotationPointCutDefinition()) && handler(*) && args(e)")
public void logCaughtException(JoinPoint thisJoinPoint, Throwable e) {
System.out.println(thisJoinPoint + " -> " + e.getClass().getCanonicalName());
}
在您的 GitHub 示例中,您将在控制台日志中看到以下行:
handler(catch(ArithmeticException)) -> java.lang.ArithmeticException
我只想对自定义注解的方法做异常处理,
喜欢下面
@Pointcut("@annotation(com.common.CollectException) && execution(* *(..))")
public void annotationPointCutDefinition() { }
@Before("annotationPointCutDefinition() && handler(*) && args(e)")
public void logCaughtException(JoinPoint thisJoinPoint, Throwable e) {
//System.out.println(e.getClass().getCanonicalName());
System.out.println("count = " +
", " +
thisJoinPoint + " -> " +
e.getClass().getCanonicalName());
}
但是对于我自定义注解标注的方法,并没有编织logCaughtException函数
@CollectException
public void divideByZeroWithCatch(){
try{
int a = 5/0;
}
catch (ArithmeticException e){
System.out.println("Can not divide by zero");
}
}
我上面的用法有误吗?如果是这样,有人会在这里给一些建议吗?
有趣的问题。你的方面代码有几个问题:
在您的 GitHub 存储库中,您使用 @within(x.y.CollectException)
。那会拦截带注释的 classes 中的连接点,但是您的示例 class 有一个带注释的方法,class 本身没有注释。因此,该切入点永远不会匹配。
在此处的示例代码中,您使用 @annotation(x.y.CollectException)
来拦截注释方法的想法是正确的。您甚至添加了 && execution(* (..))
以将匹配限制为 execution
切入点并排除 call
切入点。否则切入点将在 AspectJ 中的每个方法触发两次(在 Spring AOP 中没有 call
连接点)。到目前为止,还不错。
但是就像call
和execution
不一样所以互斥,execution
和[=21=也是]. handler
连接点通常位于 内部 的某处( 控制流 )方法执行,但它 不是 方法执行。这也是您找到解决方案的线索。您实际上想在注释方法的控制流中限制对异常处理程序的匹配:
@Pointcut("@annotation(de.scrum_master.common.CollectException) && execution(* *(..))")
public void annotationPointCutDefinition() { }
@Before("cflow(annotationPointCutDefinition()) && handler(*) && args(e)")
public void logCaughtException(JoinPoint thisJoinPoint, Throwable e) {
System.out.println(thisJoinPoint + " -> " + e.getClass().getCanonicalName());
}
在您的 GitHub 示例中,您将在控制台日志中看到以下行:
handler(catch(ArithmeticException)) -> java.lang.ArithmeticException