0

我有一堂课:

class MyClass {
    @MyAnnotation
    public void someMethod() {

    }
}

在切入点的建议中,我基本上是在提取注释所针对的“方法”。然后,根据某些配置将该方法委托给它的许多处理程序之一。

在这一点上,我必须指出,所有麻烦的根源在于我不能真正做到joinPoint.proceed()Method.invoke()某种需要在该方法上发生,因为在并行线程中有另一个委托继续调用该方法,并且该方法的执行没有ProceedingJoinPoint.

问题是,每当我执行Method.invoke()onsomeMethod时,建议会再次运行(当然),因为它上面有注释。这导致它一次又一次地运行。

我需要这样做:

  1. 如果由反射或 Method.invoke 调用,请不要运行建议(我真的不认为这是可能的)。
  2. 在建议中检测呼叫是否来自代表之一。

对于#2,我考虑设置一个标志或其他东西,但这不再保持线程安全。

有什么建议么?

更清晰的代码示例:

我有一个定义的方面:

@Pointcut("execution(@com.rohanprabhu.annotation.Process * *(..)) "
        + "&& @annotation(process)")
public void processPointcut(Process process) {
}

@Around("processPointcut(process)")
public Object process(final ProceedingJoinPoint joinPoint, final Process process)
        throws Throwable {
    final Object callingObject = joinPoint.getThis();
    final Method method = ((MethodSignature)joinPoint.getSignature()).getMethod();
    final MethodContext methodContext = new MethodContext(callingObject, method);

    //The below mentioned delegate will be picked
    //depending on some validation performed on 'callingObject'
    Object retValue = delegate.process(methodContext, joinPoint.getArgs());
    return retValue;
}

一个委托看起来像这样:

class SimpleDelegate extends Delegate {
    @Override
    public Object process(final MethodContext methodContext, final Object[] args) {
        // The problem is that following invoke call calls
        // the @Around aspect to run again, which calls the delegate again,
        // which causes execution of the next line, which causes the aspect to run
        // again and so on...
        methodContext.getMethod().invoke(
            methodContext.getCallingObject(),
            args
        );
    }
}

如果我能做类似的事情会很棒(我真的不认为有类似的事情calledByReflection

@Pointcut("execution(@com.rohanprabhu.annotation.Process * *(..)) "
        + "&& @annotation(process)" + " && !calledByReflection")
public void processPointcut(Process process) {
}

或类似的东西:

@Around("processPointcut(process)")
public Object process(final ProceedingJoinPoint joinPoint, final Process process,
               final boolean processAnnotation)
        throws Throwable {
    if(processAnnotation) {
        // Do the regular stuff
    }
}

我有一些方法可以为processAnnotationAspect 提供价值。我希望这能澄清我的问题。}

4

0 回答 0